std::set_intersection 和 std::set_union 要求两输入范围均已升序排列且元素可比较(默认用
用
std::set_intersection和std::set_union前必须排序这两个函数不是“拿来就能用”的通用交并集工具,它们要求两个输入范围都已升序排列,且元素可比较(默认用
)。如果数组没排序,直接调用会得到错误结果甚至未定义行为。实操建议:
- 先对两个原始数组分别调用
std::sort(注意:会改变原顺序;如需保留,应复制后排序)- 输出容器(如
std::vector)必须预留足够空间,或用std::back_inserter- 交集结果长度 ≤ min(两数组长度),并集结果长度 ≤ 两数组长度之和
交集结果去重,但不自动过滤重复元素
std::set_intersection的行为更接近“归并交集”:它只取**公共值的最小出现次数**。比如{1,1,2}和{1,1,1,2,2}的交集是{1,1,2}(不是{1,2}),前提是两者都已排序。常见错误现象:
- 以为它像 Python 的
set(a) & set(b)那样天然去重 → 实际不会,重复由输入决定- 传入含重复的未排序数组 → 结果完全不可预测
- 输出容器没清空或没 resize → 旧数据残留,看起来像“结果错乱”
用
std::unordered_set更贴近直觉的交/并实现如果目标是数学意义上的集合运算(自动去重、不关心顺序),用哈希容器更稳妥,也更符合日常需求。
实操建议:
- 把第一个数组所有元素插入
std::unordered_set- 遍历第二个数组,对每个元素检查是否在集合中:在 → 加入交集;不在 → 加入并集(并同时插入集合)
- 注意:
unordered_set不保证迭代顺序,如需有序结果,最后再排序输出- 时间复杂度平均 O(n+m),比排序 + 归并方式(O(n log n + m log m))在小规模或无序场景下更优
别忽略分配器和迭代器类型匹配问题
调用
std::set_intersection时,输入迭代器类型必须一致(比如不能混用int*和std::vector<int>::const_iterator</int>),输出迭代器也要能接受写入。典型报错信息:
error: no matching function for call to 'set_intersection(...)' note: candidate expects 'OutputIterator' but argument is of type 'int*'解决方案:
实际项目里,多数人真正要的不是“归并交集”,而是“值去重后的公共元素”。这时候硬套
- 统一用
std::vector::begin()/.end(),避免裸指针- 输出用
std::back_inserter(result_vec)最安全,不用手动管理容量- 若用裸数组,确保输出指针指向足够大的内存块,并用
result_ptr而非result_ptr + N作起始std::set_intersection反而绕路,unordered_set方案更直接,也更容易调试和验证。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!












