我有两个容器std::set
和std::vector
,我的任务是返回中存在的std::vector
中的元素。什么是最有效的方法来实现它? 简单解决方案: 遍历矢量元素,并在每个元素上调用set.find
,然后vector.erase
,如果未找到。在std :: set中查找std :: vector的元素
回答
你可以使用更多的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, " "));
}
如何寻找每一个元素?如果您的载体没有排序,再有就是围绕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:没有编译代码,可能会有轻微的错误。
不是100%肯定,但不是这个O(n^2)?你不需要迭代vector,然后使用set的'find'成员函数来获得O(n log n)? – NathanOliver
@NathanOliver其实我不确定。它可能是'n^2'。我有点不知所措,因为'std :: set'是排序的。 –
但是你没有搜索这个集合。 'for(auto && el:myset)'遍历这些集合,使之成为'n',然后'std :: find(myvector.begin(),myvector.end(),el);'搜索另一个'那么'O(n^2)'对吗? – NathanOliver
您应该对矢量进行排序(如有必要,请保留原始索引,制作pair
),然后使用binary search
搜索矢量。这会更快。
或者您可以使用std::find
方法,该方法可能会很慢。
很确定你不想排序,如果它没有排序。排序是O(n log n),那么你有另一个O(n log n)进程。整个过程至少可以在一个O(n log n)过程中完成。 – NathanOliver
对于一个单一的号码,你需要'n'的复杂性。由于集合中可以有多个数字,所以这个线性搜索必须重复。 – Ultraviolet
最短路可能是用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());
说明:您遍历您(O(m))准备unordered_set
。然后你遍历你的vector
一次(O(n)),每步执行unordered_set::find
(0(1))。它给你O(n + m)的复杂性。
另外,unordered_set
的大小等于set
的大小,并且良好的散列函数有助于减少std::unordered_set::find
的复杂性中的不变部分。
请参阅live example。
但是,请记住,较低的复杂度并不一定意味着在特定情况下执行速度更快(例如,由于额外分配)。
谢谢您的解释。然而(正如你所提到的),我想在不使用额外内存的情况下删除元素。 – rublow
在这种情况下,如果你不关心set的属性或者使用[boost :: multi_index_container](http://www.boost.org/doc/libs/),你可以用'unordered_set'替换'set' 1_64_0/libs/multi_index/doc/tutorial/index.html),它使用'ordered_unique'索引类型来利用'set'类属性和'hashed_unique'来过滤O(n)复杂度不需要的条目。 –
- 1. std :: set和std :: vector有什么区别?
- 2. 字符串排序 - std :: set或std :: vector?
- 3. 在自定义比较器中查找std :: set中的元素
- 4. 如何在std :: vector中查找多个元素
- 5. 查找std :: vector中的最后一个非零元素
- 6. std :: set元素消失
- 7. std :: vector元素中的const引用
- 8. std :: vector中的单个元素[C++]
- 9. 将元素从std :: vector复制到std :: set基于条件但崩溃
- 10. std :: vector和std :: deque中元素的连续存储位置
- 11. 访问std :: vector中的元素<std :: reference_wrapper <Type>>
- 12. C++ - 如何将std :: priority_queue中的元素复制到std :: vector
- 13. 从std :: vector存储到std :: set其中vector包含一个结构,但std :: set只包含结构中的一个元素
- 14. 在std :: list中保存std :: set
- 15. 需要查找std :: set元素的位置/索引
- 16. 在std :: set
- 17. 由内部的元素排序std :: vector?
- 18. std :: vector vs std :: insert
- 19. 如何到达2d std :: vector的第N个元素(`std :: vector <std :: vector <T>>`)?
- 20. std :: set ::查找异常保证
- 21. std :: vector <std :: vector <T>> vs std :: vector <T*>
- 22. 当push_back新元素到std :: vector
- 23. std :: back_inserter为std :: set?
- 24. std :: unique_locks的std :: vector向量
- 25. 从std :: vector移除元素<std::string>>
- 26. C++使用std ::指针列表重新排列std :: vector元素
- 27. iterate std :: vector <std :: vector <char>>?
- 28. 使用std :: set排序std :: list
- 29. std :: bad_alloc错误与std :: vector
- 30. 是std :: unique_ptr移入std :: vector
矢量是排序还是未排序? – NathanOliver
听起来像你可能需要像['std :: set_union'](http://en.cppreference.com/w/cpp/algorithm/set_union)(但它需要对矢量进行排序)。 –
对不一致。暂时(并且可能保持不变)向量未排序且很小。集合有更多的元素,但。 – rublow