这里我试图打印句子中每个单词的频率,该单词存储在vector
string
void display_by_word (vector<string> vs) //pass by value is necessary because we need to delete the elements.
{
vector<string> :: size_type vec_size, i;
string to_cmp = vs[0];
int occ = 0;
for ( i = 0; i < vs.size(); ++i){
vector <string> :: iterator it = vs.begin() + 1;
occ = 1;
for ( it ; it != vs.end(); ++it){
if ( vs[i] == *it){
vs.erase(it);
occ++;
}
}
cout << vs[i] << " " << occ << endl;
}
}
有时它工作正常,但有时会崩溃。有什么不对?
答案 0 :(得分:3)
请参阅http://en.cppreference.com/w/cpp/container/vector/erase
在擦除点[...]
之后或之后使迭代器和引用无效
erase
发生后,您无法重复使用it
,因为它已失效。它是未定义的行为,可能包括随机崩溃。
但是,erase
返回删除后的元素的迭代器,如果它是最后一个元素则返回end()
,这就是it = vs.erase(it);
解决方案有效的原因。
或者,请考虑使用std::remove_if
,然后使用双参数erase
,即Erase-Remove Idiom。它可能比手写循环更优雅,更可读。或者只是重写整个函数以使用std::count_if
。
答案 1 :(得分:2)
你可能想要像这样重写循环
while(it != vs.end())
{
if ( vs[i] == *it){
it = vs.erase(it);
occ++;
}
else
it++;
}
答案 2 :(得分:1)
你可以这样做: ` for(it; it!= vs.end();){
if ( vs[i] == *it){
it = vs.erase(it);
occ++;
}
else{
++it;
}
}
`