我是C ++ list 的新手。
我有两个列表:list1
和list2
。我需要在这些列表之间获得共同的元素。我怎么能得到这个?
答案 0 :(得分:7)
如果您首先对两个列表进行排序,则可以使用Here:
示例:
#include <algorithm>
#include <iostream>
#include <list>
int main() {
std::list<int> list1{2, 5, 7, 8, -3, 7};
std::list<int> list2{9, 1, 6, 3, 5, 2, 11, 0};
list1.sort();
list2.sort();
std::list<int> out;
std::set_intersection(list1.begin(), list1.end(), list2.begin(), list2.end(),
std::back_inserter(out));
for(auto k : out)
std::cout << k << ' ';
}
输出:
2 5
修改强>
上述方法可能不会是最佳方法,主要是因为对 std::list
进行排序对CPU来说并不好......
对于空间的权衡,对于较大的数据集,下面的方法肯定会更快,因为我们只迭代每个列表一次,并且每次迭代完成的所有操作都不会超过{{1}摊销的复杂性
O(1)
我使用template<typename T>
std::list<T> intersection_of(const std::list<T>& a, const std::list<T>& b){
std::list<T> rtn;
std::unordered_multiset<T> st;
std::for_each(a.begin(), a.end(), [&st](const T& k){ st.insert(k); });
std::for_each(b.begin(), b.end(),
[&st, &rtn](const T& k){
auto iter = st.find(k);
if(iter != st.end()){
rtn.push_back(k);
st.erase(iter);
}
}
);
return rtn;
}
而不是std::unordered_multiset
,因为它保留了两个列表中常见重复项的出现
我在随机生成的std::unordered_set
9000
s上为这两种方法运行std::set_intersection
,结果是(越低越好):
int
使用Average timings for 100 runs:
intersection_of: 8.16 ms
sortAndIntersect: 18.38 ms
方法的分析:
std::set_intersection
的列表1 进行排序为:N
O(Nlog(N))
的列表2 进行排序为:M
O(Mlog(M))
O(M + N)
...(一般化为对数)假设O( Nlog(N) + Mlog(M) + M + N)
和M
相等,我们可以将其概括为:N
但是如果我们使用上面发布的O(Nlog(N))
方法:
intersection_of
的列表1 进行迭代,并添加到该集合为:N
O(N) + O(1) = O(N)
的列表2 进行迭代,检查 multiset ,添加到 M
,从中删除列表2 :out
= O(M) + O(1) + O(1) + O(1)
O(M)
...(概括为线性)假设O(M + N)
和M
相等,我们可以将其概括为:N