首页 文章

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

提问于
浏览
0

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

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

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

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

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

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


    如果 binary() 的行为与你所说的相同,那么你的意图似乎是合理的: std::vector<> 中的 erase() 元素应该在删除的元素完整之前将引用和迭代器留给元素 .

    问题可能在其他地方 . 如果您发布的代码是逐字的,那么您的 if 语句中会出现格式错误:

    if(tmp!=num.end())
        num.erase(i);num.erase(tmp);res++;
    

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

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

    if(tmp!=num.end())
        {num.erase(i);num.erase(tmp);res++;}
    

相关问题