C++ 删除存在于另一个矢量中的矢量项,同时保留顺序

C++ Remove vector items that exist in another vector WHILE retaining order

本文关键字:顺序 保留 存在 删除 另一个 C++      更新时间:2023-10-16
std::vector<int> items = {1, 2, 3, 4, 5};
std::vector<int> removeItems = {2, 4};

我需要删除itemsremoveItems中的值,同时保留items的顺序。像这样:

items.remove(removeItems);

输出

项目 = {1, 3, 5}

是否有任何内置的向量方法可以实现这一点?我还没有找到任何接受另一个要删除的项目向量。如果没有,实现这一目标的最有效方法是什么?

编辑

擦除矢量中的元素 这篇文章指的是一次删除一个项目,我希望以更紧凑的方式一次删除一大堆

for(num in removeItems) {
items.erase(std::remove(items.begin(), items.end(), num), items.end())
}

因为这种删除项目的方法肯定非常低效,因为您必须检查整个items向量两次(removeItems.size()

(以removeItems

中的每个项目编辑 2

itemsremoveItems中的元素数将在 0-10000 范围内

最有效的常规形式是将removeItems转换为无序集合,然后通过检查成员资格从items中删除元素。

std::unordered_set<int> removeSet(removeItems.begin(), removeItems.end());
items.erase(std::remove_if(items.begin(), items.end(), [&](int x) {
return removeSet.count(x) != 0;
}), items.end());

如果removeItems很小,线性扫描可能比将其转换为无序集更快。对于大removeItems上述是最有效的,除非它具有非常特殊的形式(例如只有小元素(。

如果两个数组都已经排序(就像在你的例子中一样,假设这不是巧合(,你可以比上面做得更好。

您可以应用擦除删除成语,借助std::remove_ifstd::find

std::vector<int> items = {1, 2, 3, 4, 5};
std::vector<int> removeItems = {2, 4};
items.erase(std::remove_if(std::begin(items),
std::end(items),
[&removeItems](auto i) { return std::find(std::begin(removeItems), std::end(removeItems), i) != std::end(removeItems); }),
std::end(items));

请注意,std::remove_if只是将要删除的元素移动到vector的后面;这些元素稍后会被std::vector::erase擦除。