如何从std :: vector<>中删除多个元素通过索引使用擦除功能?

时间:2016-01-28 07:27:46

标签: c++ vector

我有一个向量a存储值[0 1 2 3 5]和其他向量removelist存储要删除的索引[0 1 2],以便将[3 5]留在最后。当我实现以下代码时,它会意外删除项目,因为向量a将在此过程中更改顺序。我有什么方法可以实现我的目标吗?

 for (int i = 0; i<removelist.size() ; i++)     
    a.erase(a.begin() + removelist[i]);

4 个答案:

答案 0 :(得分:2)

不一定更高效,但您可以在不使用remove_if进行排序的情况下执行此操作:

auto& rm = removelist; // for brevity

a.erase(remove_if(begin(a), end(a), [&](int i) {
  auto idx = distance(begin(v), find(begin(v), end(v), i));
  return find(begin(rm), end(rm), idx) != end(rm);
}, end(a));

答案 1 :(得分:1)

反转删除值的顺序,即使用removelist的反向迭代器。这当然取决于removelist被排序。

也许像

std::sort(removelist.begin(), removelist.end());  // Make sure the container is sorted
for (auto &i = removelist.rbegin(); i != removelist.rend(); ++ i)
{
    a.erase(a.begin() + *i);
}

答案 2 :(得分:0)

解决方案是将要保留的元素复制到新的向量中:

// pseudocode:
vector tmp;
tmp.reserve(a.size() - removelist.size());
for (i=0; i<a.size(); ++i) {
    if (i not in removelist) {
        tmp.push_back(a[i]);
    }
}
a.swap(tmp);

注意:

  • 您必须确保索引是唯一的,否则预分配将失败。
  • 这避免了使用预分配的临时向量的各种重新分配。 a的重新分配也避免了方法中的索引转换。
  • 如果对removelst中的元素进行排序,则可以更有效地实现这一点。
  • 我想知道这份名单的来源。您是否无法动态删除元素而不是创建临时列表?

答案 3 :(得分:0)

改编自@Yam Marcovic的答案,未使用dd-MON-yyyy,而是使用确切的地址来查找索引:

find