我希望你能为我澄清一些困惑。我正在编写一个函数,用于删除字符串中的重复字符,例如"AB --> "AAABB"。
void remove_dups(std::string& str) {
std::string::iterator it = str.begin();
while (it != str.end()) {
if (*(it+1) == *it) {
str.erase(it+1);
} else {
++it;
}
}
}
测试时似乎可以正常工作。但是,我想知道,难道不应该有一个“栅栏问题”吗?当'it'是字符串的结尾时,if语句会查看不存在的下一个字符。根据cplusplus.com的说法,
“超过末尾字符”是一个理论上的字符,它将跟随字符串中的最后一个字符。它不应被引用。” (http://www.cplusplus.com/reference/string/string/end/)
所以我想知道为什么我的函数似乎通过了测试,以及如何以一种优雅的方式重新编写整个函数来解决“栅栏问题”。(请对我温柔点,我是一个新手。)
重写方式如下:
void remove_dups(std::string& str) {
std::string::iterator it = str.begin();
while (it != str.end()) {
if ((it+1) != str.end() && *(it+1) == *it) {
str.erase(it+1);
} else {
++it;
}
}
}
看起来不太优雅。
std::unique
所做的。 - chrisstr.erase(std::unique(str.begin(), str.end()), str.end());
和str.resize(std::unique(str.begin(), str.end()) - str.begin());
应该会产生相同的效果,我认为两者的复杂度都差不多。 - user743382operator-
,那么一个就行不通。使用erase
的主要原因是为了使其看起来类似于擦除-删除惯用法。我没有看到resize
这个,但它应该在大部分情况下都能工作。 - chrisit-1
是一个问题(Jeffrey的答案中的end()-1
也是如此)。 (编辑:澄清一下:我知道从迭代器中减去整数与从两个迭代器中减去不同。) - user743382