This question建议使用std::set_intersection
查找两个数组的交集。不会同时使用std::find
吗?
int a[5] = {1, 2, 3, 4, 5};
int b[5] = {3, 4, 5, 6, 7};
for (int i=0; i<5; i++)
{
if (std::find(b, b+5, a[i])!=b+5)
std::cout << a[i] << std::endl;
}
std::set_intersection
基本上做同样的事情吗?或者它可能使用更有效的算法?如果std::find
需要O(n)时间,我认为上面的复杂性是O(n ^ 2)。
答案 0 :(得分:1)
对于所有(或至少几乎所有)标准库复杂性问题,a good reference可以为您解答此问题。
特别地,我们得到std::find
执行At most last - first applications of the predicate
(在这种情况下为operator<
),其中第一个和最后一个定义要搜索的范围。
我们还得到std::set_intersection
执行At most 2·(N1+N2-1) comparisons, where N1 = std::distance(first1, last1) and N2 = std::distance(first2, last2)
。
这意味着您的循环最多只能N1 * N2
operator<
个std::set_intersection
个应用,在这种情况下为25 std::set_intersection
最多可使用18个。
因此,这两种方法在它们提供相同答案的意义上“同样可以正常工作”,但{{1}}会比较少进行比较。
答案 1 :(得分:0)
std :: set是一个有序集合。这种集合有更快的方法(线性)(想想mergesort)。
答案 2 :(得分:0)
std::set::find
需要O(lg n)
,它是二进制搜索。因此,将for循环与find一起使用O(n lg n)
。 std::set_intersection
需要线性时间:对齐两个集合以找到它们的交集(类似于mergesort的合并操作)。