std::search_n是唯一专为查找连续n个相同元素设计的标准算法,仅支持严格相等(==),要求传入单个值和计数n,返回首个满足条件的迭代器,不支持自定义谓词。
直接说结论:std::search_n 是标准库中唯一专为「查找连续 n 个相同元素」设计的算法,但它不接受自定义谓词来判断“相等”,只支持严格相等(==),且要求迭代器支持随机访问以外的前向遍历即可(即 ForwardIterator 足够)。
常见误用是把它当成“找重复子序列”或“找满足条件的连续块”——它只认「值完全相同」,不处理逻辑等价(比如忽略大小写、浮点近似、指针所指对象相等等)。
n 和待匹配的**单个值**(不是范围,不是函数对象)std::vector、std::list、std::string 都可用,但 std::list 上性能是线性扫描,无优化最容易出错的是参数顺序和迭代器类型不匹配。它的签名是:
templateForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value);
注意: count 类型是 Size(通常为 或 
size_t),不是 size_t 强制要求;但若传负数,行为未定义(多数实现直接返回 last)。
first 和 last 必须构成合法范围(first ),否则未定义
value 会被逐个与容器元素用 operator== 比较——确保该类型已重载或内置支持operator==,编译失败;若定义了但逻辑不对(比如只比 ID 忽略状态),结果会出错比如想找连续 3 个「绝对值小于 0.1」的 double,或连续 2 个「name 字段相同」的 Person 对象——std::search_n 无能为力。
此时应手写循环,或组合其他算法:
std::adjacent_find + 计数器检测连续段(适合小 n)std::find_if 定位起点,再用 std::all_of 校验后续 n-1 个是否满足条件std::ranges::search_n,但依然只支持二元谓词 ==,不支持任意谓词;真要任意条件,得用 std::ranges::find 配合自定义视图例如手动检查连续 3 个正数:
auto it = std::find_if(v.begin(), v.end() - 2, [](int x) {
return x > 0 && *(v.begin() + (it - v.begin()) + 1) > 0 &&
*(v.begin() + (it - v.begin()) + 2) > 0;
});但更安全清晰的做法是写显式循环,避免迭代器算术错误。
std::search_n 对边界输入有明确定义,但容易被忽略:
count == 0:标准规定返回 first(C++11 起),即空匹配永远成功于开头count > std::distance(first, last):直接返回 last,不崩溃std::vector 上平均时间复杂度 O(n),最坏也是 O(n);但内部可能做多次比较,不如手写单次遍历高效(尤其 n 很大时)真正要注意的是:如果容器为空且 n > 0,返回 last(即 v.end()),这是合理结果,但新手常误判为“出错”。