我有一个向量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]);
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);
}
不一定更高效,但您可以使用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));
// 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
中的元素已排序,则可以更有效地实现此操作。改编自@Yam Marcovic的答案,不使用find
而是使用确切的地址来查找索引:
a.erase(std::remove_if(a.begin(), a.end(), [&](const int& i) {
auto idx = ((void*)&i - (void*)&*a.begin());
return std::find(removelist.begin(), removelist.end(), idx) != removelist.end();
}), a.end());
removelist
是否有序? - tkausl