C++中partition怎么划分区间_C++快速根据条件分类容器元素【技巧】-C++

std::partition原地重排,不保证组内顺序,返回指向首不满足元素的迭代器;与stable_partition相比开销小但不保序,使用时需注意谓词逻辑、捕获方式、副作用及迭代器有效性。

partition 会原地重排,不保证原始顺序

std::partition 把满足谓词的元素“全挪到前面”,不满足的“全挪到后面”,但同一组内的相对顺序不保留。这和 std::stable_partition 有本质区别——后者开销大但保序。

常见错误是误以为它像 filter 那样生成两个新容器;其实它只返回一个迭代器,指向第一个“不满足条件”的位置:

std::vector v = {1, 4, 2, 5, 3};
auto pivot = std::partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
// v 可能变成 {4, 2, 5, 1, 3} 或 {2, 4, 5, 1, 3} 等,只要偶数全在前、奇数全在后即可
// pivot 指向 v[2](即第一个奇数)
  • 用前先确认是否允许打乱组内顺序
  • 若需保序(比如日志按状态分组且要保持时间先后),必须换用 std::stable_partition
  • 返回的迭代器可用于快速切分:std::vector evens(v.begin(), pivot)、std::vector odds(pivot, v.end())

谓词写错会导致 partition 行为完全反直觉

传给 std::partition 的谓词决定“哪边是真值区间”。写反逻辑(比如把 x > 10 写成 x )不会报错,但结果和预期相反,而且很难一眼发现。

更隐蔽的是捕获变量时作用域失效或值变化:

立即学习“C++免费学习笔记(深入)”;

int threshold = 5;
std::partition(v.begin(), v.end(), [threshold](int x) { return x > threshold; }); // ✅ 安全
std::partition(v.begin(), v.end(), [&threshold](int x) { return x > threshold; }); // ⚠️ 若 threshold 在 partition 过程中被改,行为未定义
  • 优先用值捕获([=] 或明确变量名)而非引用捕获([&])
  • 谓词里避免副作用(如修改外部变量、打印、抛异常)——标准不保证调用次数和顺序
  • 调试时可先用 std::count_if 验证谓词逻辑:std::count_if(v.begin(), v.end(), pred) 看有多少元素应归入前段

partition 和 remove_if 的关键区别在哪

两者都重排容器,但目标不同:std::partition 是“分类”,std::remove_if 是“剔除”。前者不改变容器大小,后者需配合 erase 才真正删除。

例如想分离正负数并保留零:

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » C++中partition怎么划分区间_C++快速根据条件分类容器元素【技巧】-C++
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4023537+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4023537+
  • 本周更新: 0+
  • 最后更新: 2026-03-16