在 std::set 中查找 std::vector 的元素
Finding elements of std::vector in std::set
我有两个容器std::set
和std::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
复杂性中的常量部分。
请参阅实时示例。
但请记住,在特定情况下(例如,由于额外的分配(,较低的复杂性并不一定意味着执行速度更快。
相关文章:
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?