eve*_*odd 21 c++ string replace
我将如何做c++类似于以下代码的事情:
//Lang: Java
string.replaceAll(" ", " ");
Run Code Online (Sandbox Code Playgroud)
此代码段将使用单个空格替换字符串中的所有多个空格.
Ben*_*ley 63
bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
std::string::iterator new_end = std::unique(str.begin(), str.end(), BothAreSpaces);
str.erase(new_end, str.end());
Run Code Online (Sandbox Code Playgroud)
这是如何工作的.将std::unique有两种形式.第一种形式通过一个范围并删除相邻的重复.所以字符串"abbaaabbbb"变成"abab".我使用的第二种形式采用一个谓词,该谓词应该采用两个元素,如果它们应该被视为重复,则返回true.我写的功能就是BothAreSpaces为了这个目的.它确切地确定了它的名字含义,它的两个参数都是空格.因此,当与之结合使用时std::unique,删除重复的相邻空格.
就像std::remove并且remove_if,std::unique实际上并没有使容器变小,它只是将元素移动到接近开头的末端.它将迭代器返回到范围的新结尾,因此您可以使用它来调用erase函数,该函数是字符串类的成员函数.
将其分解,erase函数需要两个参数,一个开始和一个结束迭代器,用于擦除范围.因为它的第一个参数是我传递的返回值std::unique,因为那是我想要开始擦除的地方.对于它的第二个参数,我传递字符串的结束迭代器.
因此,我尝试了使用std :: remove_if和lambda表达式的方法-尽管在我看来,跟上面的代码相比,它更容易理解,但它并没有“哇好,没有意识到您可以做到这一点”无论如何,我仍然将其发布,仅出于学习目的:
bool prev(false);
char rem(' ');
auto iter = std::remove_if(str.begin(), str.end(), [&] (char c) -> bool {
if (c == rem && prev) {
return true;
}
prev = (c == rem);
return false;
});
in.erase(iter, in.end());
Run Code Online (Sandbox Code Playgroud)
编辑意识到std :: remove_if返回一个可以使用的迭代器..删除了不必要的代码。