从向量中擦除元素

新手上路,请多包涵

我想使用擦除方法从向量中清除一个元素。但这里的问题是,不能保证元素在向量中只出现一次。它可能出现多次,我需要清除所有这些。我的代码是这样的:

 void erase(std::vector<int>& myNumbers_in, int number_in)
{
    std::vector<int>::iterator iter = myNumbers_in.begin();
    std::vector<int>::iterator endIter = myNumbers_in.end();
    for(; iter != endIter; ++iter)
    {
        if(*iter == number_in)
        {
            myNumbers_in.erase(iter);
        }
    }
}

int main(int argc, char* argv[])
{
    std::vector<int> myNmbers;
    for(int i = 0; i < 2; ++i)
    {
        myNmbers.push_back(i);
        myNmbers.push_back(i);
    }

    erase(myNmbers, 1);

    return 0;
}

这段代码显然会崩溃,因为我在迭代它时更改了向量的结尾。实现这一目标的最佳方法是什么?即有没有办法做到这一点而无需多次迭代向量或创建一个向量的更多副本?

原文由 Naveen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 566
2 个回答

使用 删除/擦除习语

 std::vector<int>& vec = myNumbers; // use shorter name
vec.erase(std::remove(vec.begin(), vec.end(), number_in), vec.end());

发生的情况是 remove 在 --- 的开头压缩与要删除的值不同的元素( number_in vector 并返回第一个迭代器该范围之后的元素。然后 erase 删除这些元素(其值未指定)。

原文由 Motti 发布,翻译遵循 CC BY-SA 4.0 许可协议

  1. 您可以使用索引访问进行迭代,

  2. 为了避免 O(n^2) 复杂性,您可以使用两个索引,i - 当前测试索引,j - 存储下一项的索引,并在循环结束时使用新的向量大小。

代码:

 void erase(std::vector<int>& v, int num)
{
  size_t j = 0;
  for (size_t i = 0; i < v.size(); ++i) {
    if (v[i] != num) v[j++] = v[i];
  }
  // trim vector to new size
  v.resize(j);
}

在这种情况下,您没有使迭代器失效,复杂度为 O(n),并且代码非常简洁,您不需要编写一些辅助类,尽管在某些情况下使用辅助类可以受益于更灵活的代码。

此代码不使用 erase 方法,但可以解决您的任务。

使用纯 stl 您可以通过以下方式执行此操作(这类似于 Motti 的答案):

 #include <algorithm>

void erase(std::vector<int>& v, int num) {
    vector<int>::iterator it = remove(v.begin(), v.end(), num);
    v.erase(it, v.end());
}

原文由 sergtk 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题