能,但仅限于两个已排序的范围(比如 std::vector 或数组),且要求元素满足严格弱序(默认用

std::includes能判断集合包含关系吗?
能,但仅限于两个已排序的范围(比如 std::vector 或数组),且要求元素满足严格弱序(默认用 比较)。它不检查“数学意义上的子集”,而是检查“第一个范围是否按顺序包含第二个范围的所有元素”——即后者是前者的子序列(保持顺序、允许中间有其他元素)。
常见误解:传入未排序容器会得到错误结果,且无任何警告;std::includes 不做排序,也不验证输入是否有序。
怎么正确调用std::includes
必须确保两个范围都已升序排序(或按同一自定义比较器排序),然后传入首尾迭代器:
#include <algorithm>
#include <vector>
std::vector<int> a = {1, 2, 3, 4, 5};
std::vector<int> b = {2, 4};
bool result = std::includes(a.begin(), a.end(), b.begin(), b.end()); // true
</int></int></vector></algorithm>
-
a和b都必须已排序;若b = {4, 2},结果为false(即使数值上是子集) - 支持自定义比较器,例如降序:用
std::greater<int>{}</int>,但两个范围必须用同一比较器排序并传入 - 时间复杂度是线性 O(n + m),比逐个
std::find更高效
和 set::includes 或手写循环比有什么坑?
std::includes 是算法,不依赖容器类型,但容易误用:
- 对
std::set直接用std::includes(s1.begin(), s1.end(), s2.begin(), s2.end())虽然可行,但冗余——s1是有序容器,更自然的做法是遍历s2并对每个元素调用s1.find(x) != s1.end() - 若需检查多重集(multiset)中“b 的每个元素在 a 中出现次数 ≥ 在 b 中的出现次数”,
std::includes无法胜任——它只看存在性与顺序,不计频次 - 传入
std::list迭代器会编译失败(需要随机访问迭代器),实际只能用于vector、array、原生数组等
为什么我的std::includes返回false但逻辑上应该为true?
最常见原因只有两个:
- 输入范围未排序:比如
a = {5, 1, 3, 2, 4},哪怕b = {1, 2},结果也是未定义行为(通常为false) - 比较器不一致:比如
a用std::greater排序,但调用std::includes时没传对应比较器,就会用默认,导致逻辑错乱 - 注意:空容器总是被包含——
std::includes(a.begin(), a.end(), {}, {})恒为true
排序和比较器一致性不是可选项,是前提条件。漏掉任一,结果不可信。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











