C++11:std::find_if和std::remove_if应用代码片段
1、c++17之后std::string才拥有trim功能,那么c++11如何优雅的实现trim功能呢;下面摘录自https://stackoverflow.com/questions/216823/how-to-trim-a-stdstring的回答
#include
#include
#include
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch);
}));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
rtrim(s);
ltrim(s);
}
// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}
// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}
// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
return s;
}
在ltrim和rtrim中组合使用了std::erase和std::find_if来删除字符串中头尾的空格等字符。
cplusplus上演示了find_if大致的实现
template
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) return first;
++first;
}
return last;
}
很明显在pred函数返回true时立刻返回当前的迭代器,表示在first和last之间已查找到第一个符合pred要求的字符的迭代器。
2、在c中通常使用loop的方式配合strstr接口完成对一个字符串的指定子字符串进行全部删除的工作;
如:删除MAC地址中的所有“:”的功能;“11:22:33:44:55:66” -> “112233445566”
使用strstr的代码
sa=strlen(mac);
sb=strlen(":");
p=strstr(mac,":");
if(p==NULL)
cout<<"没找到,不做删除,原样输出"<<endl;
while(p!=NULL)
{
i=strlen(p);
in=sa-i;
for(j=in;j<in+sb;j++)//如果找到了子串,就把子串对应的位置改变标记
{
c[j]=1;
}
p=p+sb;
p=strstr(p,":");
}
而使用std::erase和std::remove_if只需要一行
mac.erase(std::remove_if(mac.begin(), mac.end(), [](char c) { return c == ':'; }), mac.end());
这里使用remove_if将所有需要删除的字符串移动到源字符串尾部,并返回需要删除部分的首迭代器。最后通过erase的方式删除需要删除的所有字符。