我有兩個容器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