在向量遍历时多次出现时,在向量中删除单个出现的数字

时间:2014-01-23 23:40:53

标签: c++ algorithm vector

我有一个整数向量,我正在反向遍历。我需要搜索其中的元素并在遍历向量时删除它的第一个匹配项。我正在使用以下功能并获得分段错误

for(i=num.end()-1;i!=num.begin()-1;i--)
{
    tmp=binary(*i);
    if(tmp!=num.end())
        {num.erase(i);num.erase(tmp);res++;}
}

函数binary在这里返回一个迭代器,如果要使用erase函数的语句,它的值肯定小于i。

我使用以下链接: - How to traverse vector from end to start?Erasing elements from a vector

但他们建议使用std :: remove和std :: remove_if函数来删除所有出现的值。

1 个答案:

答案 0 :(得分:0)

编辑:我错了,你的设计有缺陷。

我忽略的问题:请注意num.erase(x)使x之后的元素的引用和迭代器无效。这意味着num.erase(i);num.erase(tmp);有效tmp < i,但也意味着i之后无效。因此,在循环的下一次迭代中,循环迭代器将无效!

如果您只打算擦除这两个元素,则应在擦除后退出循环。如果您打算在端到端扫描中删除多个项目,则需要找到一些方法在最早删除点之前将循环指针前进到点。 (但是,您还应注意,从std::vector<>中间删除多个项目效率很低 - 通常从长度为N的向量中删除每个O(N)。你也可以退出循环并从最后重新开始(这就是我认为@SHR意味着“重置迭代器”)。

如果您不能执行上述任何操作,则需要一些其他类型的容器,例如std::list<>erase()不会使剩余元素的迭代器无效。此外,这些删除是O(1)(尽管你失去了快速随机访问...)


如果binary()的行为与你所说的相同,那么你的意图似乎是合理的:来自erase()的{​​{1}}元素应该在删除的元素完整之前将引用和迭代器留给元素。< / p>

问题可能在其他地方。如果您发布的代码是逐字的,那么您的std::vector<>声明中就会出现格式错误:

if

请注意,实际受if(tmp!=num.end()) num.erase(i);num.erase(tmp);res++; 条件影响的唯一语句是if - 其余语句将无条件执行。具体来说,如果num.erase(i);,它仍将执行tmp==num.end(),可能会导致细分错误....

可能的最小修复是在三个语句周围添加花括号:

num.erase(tmp)