Namespaces
Variants

std::adjacent_find

从 zh.cppreference.net
 
 
算法库
受约束算法及范围算法 (C++20)
受约束算法,例如 ranges::copy、ranges::sort、...
排序及相关操作
划分操作
(C++11)    

排序操作
二分搜索操作
(在划分后的范围上)
集合操作(在有序范围上)
合并操作(在有序范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作


 
定义于头文件 <algorithm>
template< class ForwardIt >
ForwardIt adjacent_find( ForwardIt first, ForwardIt last );
(1) (从 C++20 起为 constexpr)
template< class ForwardIt, class BinaryPred >
ForwardIt adjacent_find( ForwardIt first, ForwardIt last,
                         BinaryPred p );
(2) (从 C++20 起为 constexpr)
template< class ExecutionPolicy, class ForwardIt >
ForwardIt adjacent_find( ExecutionPolicy&& policy,
                         ForwardIt first, ForwardIt last );
(3) (从 C++17 起)
template< class ExecutionPolicy, class ForwardIt, class BinaryPred >
ForwardIt adjacent_find( ExecutionPolicy&& policy,
                         ForwardIt first, ForwardIt last,
                         BinaryPred p );
(4) (从 C++17 起)

在源范围 [first, last) 中搜索第一对满足指定条件的相邻元素。

1) 搜索第一对相等的相邻元素。相等性由 operator== 确定。
2) 搜索第一对满足给定二元谓词 p 的相邻元素。
3,4) 与 (1,2) 相同,但按照 policy 执行。
这些重载只有在以下表达式的值为 true 时才参与重载决议:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(直到 C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(从 C++20 起)

参数

first, last - 定义源范围
的迭代器对 p - true二元谓词,如果元素应被视为相等则返回 ​

。

bool pred(const Type1 &a, const Type2 &b);

谓词函数的签名应等效于以下: const &签名不需要有 Type1,但函数不得修改传递给它的对象,并且必须能够接受类型(可能为 const)Type2 和 的所有值,无论值类别Type1 &(因此, 是不允许的Type1,也不允许 Type1,除非对于 移动等同于复制(从 C++11 起)
)。Type1 类型 Type2 和 ForwardIt 必须使得类型

的对象可以被解引用并隐式转换为它们两者。 ​ policy - 要使用的执行策略
类型要求
ForwardIt- 必须满足 LegacyForwardIterator
的要求。
BinaryPred- 必须满足 BinaryPredicate

的要求。

返回值iter源范围中的第一个迭代器 true,使得以下表达式求值为

: bool(*iter == *std::next(iter))
1,3) bool(p(*iter, std::next(iter))

2,4)last如果未找到这样的迭代器,则返回

。

复杂度result给定 adjacent_find 作为 \(\scriptsize M\)Mstd::distance(first, result) 为 \(\scriptsize N\)Nstd::distance(first, last) 为

: 1)\(\scriptsize \min(M+1,N-1)\)min(M+1,N-1)operator== 次使用
进行比较。2)\(\scriptsize \min(M+1,N-1)\)min(M+1,N-1)p 次应用谓词
。 \(\scriptsize \mathcal{O}(N)\)𝓞(N)operator== 次使用
进行比较。 \(\scriptsize \mathcal{O}(N)\)𝓞(N)p 次应用谓词

。

)。

可能的实现
template<class ForwardIt>
ForwardIt adjacent_find(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return last;
    
    ForwardIt next = first;
    ++next;
    
    for (; next != last; ++next, ++first)
        if (*first == *next)
            return first;
    
    return last;
}
adjacent_find (1)
template<class ForwardIt, class BinaryPred>
ForwardIt adjacent_find(ForwardIt first, ForwardIt last, BinaryPred p)
{
    if (first == last)
        return last;
    
    ForwardIt next = first;
    ++next;
    
    for (; next != last; ++next, ++first)
        if (p(*first, *next))
            return first;
    
    return last;
}

adjacent_find (2)

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v1{0, 1, 2, 3, 40, 40, 41, 41, 5};
    
    auto i1 = std::adjacent_find(v1.begin(), v1.end());
    
    if (i1 == v1.end())
        std::cout << "No matching adjacent elements\n";
    else
        std::cout << "The first adjacent pair of equal elements is at "
                  << std::distance(v1.begin(), i1) << ", *i1 = "
                  << *i1 << '\n';
    
    auto i2 = std::adjacent_find(v1.begin(), v1.end(), std::greater<int>());
    if (i2 == v1.end())
        std::cout << "The entire vector is sorted in ascending order\n";
    else
        std::cout << "The last element in the non-decreasing subsequence is at "
                  << std::distance(v1.begin(), i2) << ", *i2 = " << *i2 << '\n';
}

运行此代码

The first adjacent pair of equal elements is at 4, *i1 = 40
The last element in the non-decreasing subsequence is at 7, *i2 = 41

输出:

缺陷报告

以下行为更改的缺陷报告已追溯应用于先前发布的 C++ 标准。 DR 应用至 发布时的行为
正确行为 LWG 240 C++98 复杂度要求不明确

已澄清

ranges::adjacent_find
(C++20)
查找相等(或满足给定谓词)的前两个相邻项
unique
移除范围中的连续重复元素&(函数模板
ranges::unique
(C++20)