从第一个集合中删除第二个集合中包含的元素,不迭代

Remove elements from first set element which second set contains without iteration

本文关键字:集合 元素 迭代 第二个 第一个 删除 包含      更新时间:2023-10-16

我有两组对(我不能使用c++11)

std::set<std::pair<int,int> > first;
std::set<std::pair<int,int> > second;

和我需要从第一个集合中删除第二个集合中的所有元素(如果第一个包含第二个要删除的元素)。我可以通过迭代第二个集合来做到这一点,如果第一个集合包含相同的元素,从第一个元素中删除,但我想知道有没有办法不迭代做到这一点?

如果我理解正确的话,基本上你想计算第一和第二的差。这里有一个<algorithm>函数。

std::set<std::pair<int, int>> result;
std::set_difference(first.begin(), first.end(), second.begin(), second.end(), inserter(result, result.end()));

可以。

如果您想删除,而不仅仅是检测,这是这里的另一个<algorithm>函数:remove_copy_if():

http://www.cplusplus.com/reference/algorithm/remove_copy_if/

恕我直言。要理解它的工作原理并不难。

我想知道有没有办法不用迭代就能做到这一点。

。在内部,集合是平衡二叉树——没有办法在不迭代结构的情况下对它们进行操作。(我假设您对实现的效率感兴趣,而不是代码的便利性,所以我故意忽略了必须在内部迭代的库例程)。

集合是排序的,所以你可以在每个集合上进行迭代,删除(所以# operations是集合大小的总和),而不是迭代和查找每个元素(其中操作次数是你迭代的元素数量乘以另一个集合中元素数量的log以2为底)。只有当你的一个集合比另一个集合小得多时,迭代/查找方法才会胜出。如果你看一下你的库的set_difference函数的实现(在Amen的回答中提到),它应该会告诉你如何很好地完成这两个迭代。

如果你想要更有效的东西,你需要考虑如何更早地实现这一点:例如,将你的对作为标志存储在相同大小的二维矩阵中,这样你就可以与第二个集合的负数进行AND运算。这是否实际取决于您要存储的int值的范围,所需的内存量是否适合您的目的....