【问题标题】:C++ Remove vector items that exist in another vector WHILE retaining orderC++ 删除存在于另一个向量中的向量项,同时保留顺序
【发布时间】:2020-06-05 15:33:39
【问题描述】:
std::vector<int> items = {1, 2, 3, 4, 5};
std::vector<int> removeItems = {2, 4};

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

items.remove(removeItems);

输出

项目 = {1, 3, 5}

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

编辑

Erasing elements from a vector 这篇文章是指一次删除一个项目,我希望以更紧凑的方式一次删除一大堆

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

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

编辑 2

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

【问题讨论】:

  • stackoverflow.com/a/347478/783510 我想你正在寻找所谓的“删除/擦除”成语
  • @PhilippClaßen 否,因为他们一次删除单个成员。我希望一次完成所有工作
  • “我希望以一种更紧凑的方式一次删除一大堆”它只是组合......把它放在一个函数中!!

标签: c++ vector iterator


【解决方案1】:

最有效的一般形式是将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,上面的方法是最有效的,除非它有非常特殊的形式(比如只有小元素)。

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

【讨论】:

  • 老实说,removeItems 这么小,坚持使用向量并执行 O(n*m) 搜索序列可能会更快。跨度>
  • @AsteroidsWithWings 可能,但我不知道 真实 removeItems 有多大。此解决方案随items/removeItems 的任意数量线性缩放,而保持向量是二次的。
  • 是的,它可以扩展,但在您要删除许多元素之前,实际性能会更差。在编写代码时,我们应该考虑现实而不仅仅是理论上的扩展。至少答案应该提到这一点。
  • @cdhowie 不需要吗?
  • 非常感谢!工作就像一个魅力,我有一种预感,可能与它有关!
【解决方案2】:

您可以在std::remove_ifstd::find 的帮助下申请erase-remove idiom

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 删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多