如何在C++中应用两个列表之间的交集
How to apply the intersection between two lists in C++?
我是C++列表的新手。
我有两个列表:list1
和list2
。我需要获取这些列表之间的通用元素。我怎么能拿到这个?
您可以使用:std::set_intersection
,前提是您首先对两个列表进行排序:
示例:
#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不好。。。
为了权衡空间,对于较大的数据集,下面的方法肯定会更快,因为我们只对每个列表进行一次迭代,并且每次迭代中完成的所有操作都不会超过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
int
s上为这两种方法运行了一个肮脏的基准测试,结果是(越低越好(:
Average timings for 100 runs:
intersection_of: 8.16 ms
sortAndIntersect: 18.38 ms
使用std::set_intersection
方法的分析:
- 排序大小为
N
的列表1为:O(Nlog(N))
- 排序大小为
M
的列表2为:O(Mlog(M))
- 寻找交集是:
O(M + N)
- 总计:
O( Nlog(N) + Mlog(M) + M + N)
。。。(广义为对数(
假设M
和N
相等,我们可以将其推广为:O(Nlog(N))
但如果我们使用我上面发布的intersection_of
方法:
- 遍历大小为
N
的列表1并添加到集合中为:O(N) + O(1) = O(N)
- 遍历大小为
M
的列表2,检查多集、添加到out
并从中删除:O(M) + O(1) + O(1) + O(1)
=O(M)
- 总计:
O(M + N)
。。。(广义为线性(
假设M
和N
相等,我们可以将其推广为:O(N)
相关文章:
- 测试两个类型列表中的所有组合
- 创建一个棋盘格或"Interweave"两个链接列表。IE 更改两个链表的指针
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 我如何创建一个列表,然后从中创建两个列表,其中一个用于偶数,另一个用于奇数?
- C++如果两个模板函数都与参数列表匹配,将调用哪个模板
- 如何在两个列表中比较和获取非包含值
- 如何在构造器的成员初始值设定项列表中调用两个函数?
- 将两个列表合并为一个蛇形列表
- C++ 分段错误:11 错误,同时编码将两个数字相加的链接列表
- 使用特征查找两个列表之间的差异
- 如何在这两个分类的链接列表之间获得开关的位置
- 如何合并两个双重链接列表(访问下一个链接)
- 通过单词列表将两个字符串移动以比较每个单词
- 添加一个节点,并在通用树中的两个给定节点之间找到路径成本,其中c 中的儿童列表
- 如何比较C 列表中的两个连续元素
- 两个排序的链接列表C 的交点
- 如何在两个包含指针的地图中创建列表
- 合并两个单链接列表以形成第三个列表的功能
- 两个单链列表共享同一个节点和析构函数两次删除相同的内存