在 std::set 中查找 std::vector 的元素

Finding elements of std::vector in std::set

本文关键字:std vector 元素 set 查找      更新时间:2023-10-16

我有两个容器std::setstd::vector,我的任务是从std::set中存在的std::vector返回元素。实现它最有效的方法是什么? 简单的解决方案: 遍历 vector 元素并调用每个元素set.find,如果未找到,则vector.erase

只寻找每个元素怎么样?如果您的向量未排序,则无法绕过n log(n)

#include <algorithm>
std::vector<int> result;
for(auto&& el: myvector) {
auto it_found = myset.find(el);
if(it != myset.end())
result.push_back(*it_found);
}

现在result拥有两者中的所有元素。

PS:尚未编译代码,可能会有轻微错误。

您可以使用更多的 STL :)

#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
#include <iterator>
int main() {
std::vector<int> v {5, 4, 3, 2, 1};
std::set<int> s {1, 3, 5};
v.erase(std::remove_if(v.begin(), v.end(), 
[&s](int a) { return s.find(a) == s.end(); }),
v.end());
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
}

最短的方法可能是使用std::set_intersection。但是你应该对一个向量进行排序以使其工作:

int main()
{
std::set<int>    s{1,2,3,4,5,6,7,8};
std::vector<int> v{7,5,10,9};
std::sort(v.begin(), v.end()); // should not bother you if vector is small
std::vector<int> intersection;
std::set_intersection(s.begin(), s.end(), v.begin(), v.end(), std::back_inserter(intersection));
for(int n : intersection)
std::cout << n << ' ';
}

印刷品:5 7

根据集合和向量的相对大小,remove_if可能是正确的选择...

#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
std::set<int>    s{1,2,3,4,5,6,7,8};
std::vector<int> v{7,5,10,9};
v.erase(std::remove_if(v.begin(), v.end(), [&](int e){return s.count(e) == 0;}), v.end());

for(int n : v)
std::cout << n << ' ';
}

如果你在复杂性方面寻找最有效的CPU方法,有额外的内存和一个好的哈希函数,你可以在O(n + m(中做到这一点:

std::vector<int> v;
std::set<int> s;
std::unordered_set<int> us{s.cbegin(), s.cend(), s.size()};
v.erase(
std::remove_if(v.begin(), v.end(),
[&us] (const int entry) { return us.find(entry) == us.cend(); }),
v.end());

说明:您遍历一次set(O(m(( 以准备unordered_set。然后循环访问vector一次 (O(n((,每一步执行unordered_set::find(0(1((。它为您提供了 O(n+m( 的复杂度。

此外,unordered_set的大小等于set的大小,良好的哈希函数有助于减少std::unordered_set::find复杂性中的常量部分。

请参阅实时示例

但请记住,在特定情况下(例如,由于额外的分配(,较低的复杂性并不一定意味着执行速度更快。