std::adjacent_find默认查找首对相邻相等元素,返回指向第一个的迭代器;可自定义谓词判断相邻关系,如递增差1或浮点近似相等,不修改容器且短路查找。

std::adjacent_find 默认行为是找相邻相等元素
它从左到右扫描迭代器范围,一旦发现 *(it) 和 *(it + 1) 相等,就返回指向第一个元素的迭代器。没找到则返回末尾迭代器(如 v.end())。
常见错误是误以为它返回重复块的起始位置(比如三个连续相同元素时,它只返回前两个中的第一个),其实它只保证找到「某一对相邻相等」,不关心后续是否还连着。
- 对
std::vector<int>{1,2,2,2,3}</int>调用std::adjacent_find(v.begin(), v.end()),返回指向第二个元素(第一个2)的迭代器 - 若容器为空或只有 1 个元素,安全调用但必然返回
end() - 注意:它不修改原容器,也不保证“最左最长”,只做一次短路查找
自定义谓词判断相邻关系要传入第 3 个参数
默认用 operator==,但你可以传入二元谓词,比如找差值为 1 的递增相邻对、绝对值差小于阈值的浮点近似相等、或字符串忽略大小写比较。
谓词接收两个参数:*(it) 和 *(it + 1),返回 true 表示满足条件。
- 找相邻递增(后比前大 1):
std::adjacent_find(v.begin(), v.end(), [](int a, int b) { return b - a == 1; }) - 浮点近似相等(避免直接
==):[](double a, double b) { return std::abs(a - b) - 字符串忽略大小写:
[](const std::string& a, const std::string& b) { return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char x, char y) { return std::tolower(x) == std::tolower(y); }); }
查不到时必须检查返回值是否等于 end() 才能安全解引用
这是最容易崩的地方——直接对返回的迭代器取值,没判 == container.end(),就会触发未定义行为(UB),尤其在 Release 模式下可能不报错但结果随机。
- 正确写法:
auto it = std::adjacent_find(v.begin(), v.end());<br>if (it != v.end()) {<br> std::cout } - 错误写法:
std::cout —— 容器无重复时解引用 <code>v.end() - 如果用在算法链式调用中(比如传给
std::distance),也得先确保有效
和 std::unique、std::adjacent_difference 的关键区别在哪
std::adjacent_find 是只读查找,不改变数据;而 std::unique 会移动元素并返回新逻辑结尾,常被误当成“去重函数”但其实不真正擦除;std::adjacent_difference 是计算差分,和查找完全无关。
- 想“删掉所有相邻重复,只留一个”,该用
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());,不是adjacent_find - 想“统计有多少组相邻重复”,不能只调一次
adjacent_find,得循环查找(每次从上一结果+1开始) - 性能上:
adjacent_find是 O(n) 单次扫描,最坏遍历全部;无需额外空间
它本质是个“短路搜索工具”,适合快速响应“有没有相邻重复”这类布尔型判断,别指望它返回重复段长度或全部位置。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











