c++中如何求两个集合的交集_c++ set_intersection用法


std::set_intersection要求两输入区间均已升序排列,仅接受迭代器范围而非容器本身;对vector需先sort,对set可直接用begin()/end();输出须用独立容器配合back_inserter或手动resize截断,且自定义比较器必须一致。

set_intersection 要求输入是已排序区间

std::set_intersection 不接受 std::set 对象直接传入,它只操作**迭代器范围**,且明确要求两个输入范围都已升序排列。如果你拿 std::vector 或原始数组调用它,必须先确保它们有序;若用 std::set,虽然其内部有序,但你仍需传入 begin()/end() 迭代器,不能传容器本身。

常见错误是把无序 std::vector 直接送进去,结果输出为空或乱序片段——这不是函数 bug,而是前提不满足。

  • std::set:可直接用 s1.begin(), s1.end(), s2.begin(), s2.end()
  • std::vector:务必先调用 std::sort,否则行为未定义
  • 输出容器(如 std::vector)需预留足够空间,或用 std::back_inserter

输出目标必须能接收插入,且不能和输入重叠

输出迭代器指向的目标容器不能是任一输入容器的子区间,也不能与输入迭代器指向的内存重叠——否则结果未定义。最安全做法是用独立容器 + std::back_inserter

例如,不能写成 set_intersection(a.begin(), a.end(), b.begin(), b.end(), a.begin()),即使 a 足够大也不行;也不能用 std::array 的原生指针而没确认长度。

  • 推荐:用 std::vector result; set_intersection(..., std::back_inserter(result))
  • 手动分配空间:需先调用 result.resize(std::min(a.size(), b.size())),再用 result.begin(),最后用 result.erase(it, result.end()) 截断
  • 输出类型必须和输入元素类型一致或可隐式转换

自定义比较函数要两边一致

如果集合按降序排列,或用了自定义比较(比如 std::set>),那么 set_intersection 的第五个参数必须传入**完全相同的比较器**,否则逻辑错乱。

例如,两个 std::set<:string std::less>> 可以直接用默认版本;但若其中一个是 std::greater,就必须显式传入对应函数对象。

  • 默认调用:set_intersection(a.begin(), a.end(), b.begin(), b.end(), out)
  • 自定义比较:set_intersection(a.begin(), a.end(), b.begin(), b.end(), out, std::greater{})
  • lambda 也可,但注意生命周期:不能捕获局部变量并用于多线程场景

完整可用示例(含 vector 和 set 两种情况)

#include 
#include 
#include 
#include 

int main() {
    // 情况1:两个 std::set(天然有序)
    std::set s1 = {1, 3, 5, 7, 9};
    std::set s2 = {3, 4, 5, 6, 7};
    std::vector v_result;
    std::set_intersection(s1.begin(), s1.end(),
                          s2.begin(), s2.end(),
                          std::back_inserter(v_result));
    // v_result == {3, 5, 7}

    // 情况2:两个 vector(需先排序)
    std::vector v1 = {5, 1, 7, 3};
    std::vector v2 = {7, 4, 3, 6};
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
    std::vector v2_result;
    std::set_intersection(v1.begin(), v1.end(),
                          v2.begin(), v2.end(),
                          std::back_inserter(v2_result));
    // v2_result == {3, 7}
}

注意:std::set_intersection 返回的是输出迭代器末位置,不返回交集大小;如果需要,得自己算 std::distance 或依赖 back_inserter 后容器的 size()。实际项目中,除非性能极端敏感,否则优先用 back_inserter —— 它省去容量预估,也避免越界风险。


# go  # ai  # c++  # ios  # stream  # 排列  # 隐式转换  # less  # String  # Array  # sort  # 局部变量  # int  # Lambda  # 指针  # 线程  # 多线程  # 对象  # bug  # 自定义  # 迭代  # 升序  # 也不  # 可直接  # 的是  # 如果你  # 两种  # 也可  # 用了 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Win11怎么更改管理员名字 Win11修改账户名称详细步骤【教程】  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  如何解决同一段404代码在不同主机上表现不一致的问题  Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡时长设置【步骤】  Win11怎么清理C盘系统日志_Win11清理系统日志文件【步骤】  Win11怎么设置默认浏览器Chrome_Windows11修改默认网页打开方式  为什么本地php环境运行php脚本卡顿_php执行效率优化方法与设置【说明】  PHP cURL GET请求:正确设置认证与自定义请求头的完整教程  php报错怎么查看_定位PHP致命错误与警告的方法【教程】  如何在 ACF 中正确更新嵌套多层的 Group 字段子字段  c# await 一个已经完成的Task会发生什么  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  MySQL 中使用 IF 和 CASE 实现查询字段的条件转换  Win11怎么关闭定位服务_保护Win11位置隐私设置指南【详解】  windows 10专注助手怎么关闭_windows 10禁用通知提醒功能方法  Win11怎么更改文件夹图标_自定义Win11文件夹外观样式【详解】  Windows10如何查看保存的WiFi密码_Win10命令行netsh wlan查询  Win11怎么关闭搜索历史 Win11清除搜索框最近记录【隐私】  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  Win11色盲模式怎么开_Win11屏幕颜色滤镜设置【关怀】  Win11怎么设置开机自动连接宽带_Windows11创建拨号连接计划任务  Win11怎么自动隐藏任务栏_Win11全屏显示设置【美化】  Django密码修改后会话失效的解决方案  Python对象比较与排序_集合使用说明【指导】  c++如何利用doxygen生成开发文档_c++ 代码注释规范与HTML文档导出【案例】  Win11怎样安装微信开发者工具_Win11安装开发者工具教程【步骤】  c++输入输出流 c++ cin与cout格式化输出【方法】  Win10电脑怎么设置休眠快捷键_Windows10电源按钮功能定义  Win11如何设置鼠标灵敏度_Win11鼠标灵敏度调整教程【攻略】  如何在 Go 中正确反序列化 XML 多节点数组(解决仅解析首个元素的问题)  Win11怎么恢复旧版开始菜单_通过软件还原Win10风格菜单【详解】  c++怎么实现大文件的分块读写_c++ 文件指针seekp与seekg偏移控制【方法】  如何在Windows中创建新的用户账户?(标准与管理员)  Python安全爬虫设计_IP代理池与验证码识别策略解析  为什么Go建议使用error接口作为错误返回_Go Error接口设计原因说明  怎么将XML数据可视化 D3.js加载XML  Python数据挖掘进阶教程_分类回归与聚类案例解析  php转mp4怎么设置帧率_调整php生成mp4视频帧率说明【说明】  短链接怎么用php还原_从基础原理到代码实现教学【详解】  c++ std::atomic如何保证原子性 c++ CAS操作原理【底层】  php订单日志怎么在swoole写_php协程swoole写订单日志教程【教程】  如何在Golang中实现WebSocket广播_使用Channel和协程分发消息  Win11如何设置系统声音_Win11系统声音调整教程【攻略】  Win11怎么关闭VBS安全性_Windows11提升游戏性能关闭虚拟化安全  如何从 Go 的 map[string]interface{} 中安全获取值  c++中如何使用虚函数实现多态_c++多态性实现原理  如何使用Golang实现Web表单数据绑定_自动映射字段到结构体  Win10电脑怎么设置网络名称_Windows10注册表NetworkList修改  Windows10如何彻底关闭自动更新_Win10服务与组策略双重禁用  PythonPandas数据分析项目教程_时间序列透视表应用 

 2026-01-04

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.