我尝试使用isWordChar()方法从字符串中删除特殊字符。但是,我需要保留两个特殊字符," ' "和" - ",例如"中的撇号不是"#34;和婆婆的连字符。这是我尝试实施的内容:
std::string WordCount::stripWord(std::string word) {
for(unsigned int i = 0; i < wrd.size(); ++i)
{
if( !isWordChar(wrd[i]) && (wrd[i]!=39 && wrd[i]!=45))
{
wrd.erase(wrd.begin()+i);
--i;
}
}
return wrd;
}
在我的布尔值中添加特殊情况后,我似乎无法正确添加异常。任何提示或建议?谢谢!
答案 0 :(得分:3)
我会使用删除/删除习语:
word.erase(std::remove_if(word.begin(),
word.end(),
[](char c) {
return !(isWordChar(c) || '-' == c || '\'' == c);
}), word.end());
您删除字符的方式的复杂程度约为O(N * M)(其中N是字符串的原始长度,M是您删除的字符数)。这具有大约O(N)的复杂度,因此如果您要删除很多字符(或字符串很长),它可能会显着提高速度。
如果你关心它为什么这么快,那是因为它的工作方式有些不同。具体来说,当您从字符串中间删除元素时,擦除功能会立即复制所有字母后填充删除字符的孔。如果这样做M次,那么为你删除的每个字符复制一个所有这些字符。
当您使用remove_if
时,它会执行更类似的操作:
template <class Iter, class F>
Iter remove_if(Iter b, iter e, F f)
auto dest = word.begin();
for (auto src=word.begin(); src != word.end(); ++src)
if (!f(*src))
*dst++ = *src;
++src;
}
return dst;
}
这样,每个保留的字符只复制一次,而不是每次从字符串中删除一个字符时复制。然后当你做最后的erase
时,它只是从字符串的末尾删除字符,所以它基本上只是向下调整字符串的长度。
答案 1 :(得分:1)
你的逻辑错误。它应该是:!isWordChar(wrd[i]) && wrd[i] != 39 && wrd[i] != 45
。读作:如果字符不是单词字符,并且它不是撇号,并且它不是连字符,请执行if语句中的任何内容。