C++中的无序集合交集
unordered set intersection in C++
这是我的代码,想知道有什么想法可以使其更快吗?我的实现是蛮力,它是针对 a 中的任何元素,尝试查找它是否也在 b 中,如果是,则放入结果集 c。任何更聪明的想法都会受到赞赏。
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> a = {1,2,3,4,5};
std::unordered_set<int> b = {3,4,5,6,7};
std::unordered_set<int> c;
for (auto i = a.begin(); i != a.end(); i++) {
if (b.find(*i) != b.end()) c.insert(*i);
}
for (int v : c) {
std::printf("%d n", v);
}
}
渐近地,你的算法是最好的。
在实践中,我会添加一个检查来循环两个集合中较小的一个,并在较大的集合中进行查找。假设哈希分布合理均匀,std::unoredered_set
中的查找需要恒定的时间。因此,这样,您将执行更少的此类查找。
你可以用std::copy_if()来做到这一点
。std::copy_if(a.begin(), a.end(), std::inserter(c, c.begin()), [b](const int element){return b.count(element) > 0;} );
对于无序集合,您的算法与它一样好。 但是,如果您使用std::set
(使用二叉树作为存储)甚至更好的排序std::vector
,则可以做得更好。算法应该是这样的:
- 让迭代器
a.begin()
和b.begin()
如果迭代器 - 指向相等元素,则添加到交集并递增两个迭代器。 否则,将
- 指向最小值的迭代器递增
- 转到 2。
两者都应该是 O(n) 时间,但使用普通集合应该可以避免计算哈希或哈希冲突引起的任何性能下降。
谢谢 Angew,为什么你的方法更快?你能详细说明一下吗?
好吧,让我为您提供一些额外的信息...
应该很清楚的是,无论您使用哪种数据结构,您都必须迭代其中至少一个中的所有元素,因此您不能比O(n)
更好,n
是数据结构中选择要迭代的元素数量。现在的基本问题是,你可以多快地查找另一个结构中的元素——使用哈希集,实际上是std::unordered_set
,这是O(1)
的——至少如果碰撞次数足够小("合理均匀分布的哈希">);退化的情况将是所有具有相同键的值...
到目前为止,你得到O(n) * O(1) = O(n)
.但是你仍然可以选择:O(n)
或O(m)
,如果m
是另一个集合中的元素数量。好的,在复杂度计算中,这是相同的,反正我们有一个线性算法,但在实践中,如果你选择元素数量较少的集合,你可以省去一些哈希计算和查找......
- c++找不到具有相同哈希的无序集合元素
- 如何写向量的无序向量集,即unordered_set<向量<向量<int>>集合?
- 从C++无序集合中高效提取元素
- 打印无序映射的第二个元素,即集合
- 如何将一个单词拆分成字母,并将它们放入一个无序的列表/集合中
- 仅从无序集合中删除一个项目
- 如何从一个无序集合中获取一个元素
- C++中的无序集合交集
- 设置要与无序集合一起使用的自定义类 - 在集合中找不到元素
- 使用shared_ptr<字符串>转换为一个无序集合<字符串>
- 如何将数组插入无序集合
- 将向量的元素添加到无序集合中
- 为什么这些C++ STL 无序集合不被视为相等?
- 打印无序集合的元素
- 无序集合中的哈希函数
- std::插入无序集合(或映射)的迭代器
- 比较两个无序集合的相等性有多昂贵
- 相当于 python 的 set.pop() 用于C++的无序集合
- 如何在C++中迭代一个无序的集合
- C++:将元素从无序集合复制到向量