|
-
September 2nd, 2009, 06:57 AM
#1
remove_if (not)
Basically, I have a string, and I want to remove all non alpha chars.
I'm trying to do it using algorithm, so I thought I'd do something like this:
Code:
iString.erase(
std::remove_if(iString.begin(), iString.end(), &isalpha),
iString.end()
);
The problem is that this removes all the alpha, the oposite of what I want to do.
I would use the algorithm std::copy_if or remove_if_not, but they don't exist. My other choice would be to pass std::not1(isalpha), but that doesn't work, since isalpha is not a function object.
I could write this:
Code:
struct isalphafuntor : public std::unary_function<int,bool>
{
bool operator()(int iChar) const
{
return isalpha(iChar);
}
};
But I would rather avoid it.
So my question is this one:
Can I, in a single line, pass the negated isalpha function to the remove if algorithm? or am I stuck with wrapping isalpha explicitly (or writting isnotalpha)?
-
September 2nd, 2009, 07:25 AM
#2
Re: remove_if (not)
>> My other choice would be to pass std::not1(isalpha), but that doesn't work ...
You can force the compiler to use the function instead of the macro with "&(::isalpha)". Or just use the C++ version from <locale>.
gg
-
September 2nd, 2009, 07:32 AM
#3
Re: remove_if (not)
 Originally Posted by Codeplug
>> My other choice would be to pass std::not1(isalpha), but that doesn't work ...
You can force the compiler to use the function instead of the macro with "&(::isalpha)". Or just use the C++ version from <locale>.
gg
I don't understand your solution. The problem with not1 is that it takes a function object, and not a function, so that doesn't solve the problem. same with the one from locale.
Or maybe I'm missing something?
-
September 2nd, 2009, 07:44 AM
#4
Re: remove_if (not)
Predicate objects in STL can be functions or objects.
gg
-
September 2nd, 2009, 08:30 AM
#5
Re: remove_if (not)
 Originally Posted by Codeplug
Predicate objects in STL can be functions or objects.
gg
Yes, that's why I can pass isalpha as an argument. however, I'm having trouble building a not1(isalpha) function. Not1 takes only function objects.
How can I negate a function, and pass the result as an argument?
-
September 2nd, 2009, 08:45 AM
#6
Re: remove_if (not)
 Originally Posted by monarch_dodra
Yes, that's why I can pass isalpha as an argument. however, I'm having trouble building a not1(isalpha) function. Not1 takes only function objects.
How can I negate a function, and pass the result as an argument?
That's what std::ptr_fun from the functional header's for.
-
September 2nd, 2009, 09:09 AM
#7
Re: remove_if (not)
 Originally Posted by Plasmator
That's what std::ptr_fun from the functional header's for.
*facepalms* thankyou Plasmator, that's what I was looking for. And here is what I wrote.
Code:
void lcase(std::string& ioString)
{
ioString.erase(
std::remove_if(ioString.begin(), ioString.end(), std::not1(std::ptr_fun(&isalpha))),
ioString.end()
);
std::transform(ioString.begin(), ioString.end(), ioString.begin(), std::ptr_fun(&tolower));
}
I'm wondering though, which is more efficient?
Code:
std::transform(ioString.begin(), ioString.end(), ioString.begin(), &tolower);
or
std::transform(ioString.begin(), ioString.end(), ioString.begin(), std::ptr_fun(&tolower));
Is there a difference in performance? I heard function objects are faster because the compiler can inline them, but in this case, the end result is that isalpha still has to be called?
-
September 2nd, 2009, 09:25 AM
#8
Re: remove_if (not)
>> That's what std::ptr_fun from the functional header's for.
Right...sorry, I got stuck on function vs. macro. std::ptr_fun will make it adaptable when it's needed.
Code:
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
using namespace std;
int main()
{
string s = "a1b23c";
s.erase(remove_if(s.begin(), s.end(), not1(ptr_fun(&(::isalpha)))),
s.end());
cout << s << endl;
return 0;
}//main
gg
-
September 2nd, 2009, 09:32 AM
#9
Re: remove_if (not)
>> I'm wondering though, which is more efficient?
Premature optimization?...
I would say they are identical since std::ptr_fun will most likely be optimized away.
For maximum [premature] optimization, you could write a predicate object that used the macro version of tolower. Or assume A-Z and a-z and do it yourself.
gg
-
September 2nd, 2009, 09:43 AM
#10
Re: remove_if (not)
 Originally Posted by Codeplug
>> I'm wondering though, which is more efficient?
Premature optimization?...
I would say they are identical since std:  tr_fun will most likely be optimized away.
For maximum [premature] optimization, you could write a predicate object that used the macro version of tolower. Or assume A-Z and a-z and do it yourself.
gg
I wouldn't call it premature optimization but more of a best practice. I'm not looking to optimize, just to find out which one is best, in general. Thanks anyways
-
September 2nd, 2009, 12:55 PM
#11
Re: remove_if (not)
 Originally Posted by monarch_dodra
I'm wondering though, which is more efficient?
Code:
std::transform(ioString.begin(), ioString.end(), ioString.begin(), &tolower);
or
std::transform(ioString.begin(), ioString.end(), ioString.begin(), std::ptr_fun(&tolower));
Is there a difference in performance? I heard function objects are faster because the compiler can inline them, but in this case, the end result is that isalpha still has to be called?
I've read the same thing but I don't think that it justifies turning a library function into a functor in this case. I have a hard time believing that it would significantly improve your program. If you were writing your own predicate, as opposed to using a std library function, then I would always choose a functor over writing a global or static member function. Even then I'm not sure if the performance boost is really significant. I do it because I like the object orientedness of using functors, for lack of a better phrase. When passing a predicate by value to an algorithm, the functor concept seems more intuitive to me but I have never even bothered to measure the performance difference.
If you really wanted to know, you'd have to write a couple of sample programs and study the assembly code of each. You could also use some timestamps or a profiling tool to study the differences if you want. it might be useful to do that one time just to see for yourself what kind of a difference there is.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|