std:: search_n
|
定义于头文件
<algorithm>
|
||
| (1) | ||
|
template
<
class
ForwardIt,
class
Size,
class
T
>
ForwardIt search_n
(
ForwardIt first, ForwardIt last,
|
(自 C++20 起为 constexpr)
(C++26 前) |
|
|
template
<
class
ForwardIt,
class
Size,
class
T
=
typename
std::
iterator_traits
|
(自 C++26 起) | |
| (2) | ||
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
Size,
class
T
>
|
(自 C++17 起)
(C++26 前) |
|
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
Size,
|
(自 C++26 起) | |
| (3) | ||
|
template
<
class
ForwardIt,
class
Size,
class
T,
class
BinaryPred
>
ForwardIt search_n
(
ForwardIt first, ForwardIt last,
|
(自 C++20 起为 constexpr)
(C++26 前) |
|
|
template
<
class
ForwardIt,
class
Size,
class
T
=
typename
std::
iterator_traits
|
(自 C++26 起) | |
| (4) | ||
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
Size,
class
T,
class
BinaryPred
>
|
(自 C++17 起)
(C++26 前) |
|
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
Size,
class
T
=
typename
std::
iterator_traits
|
(自 C++26 起) | |
在范围
[
first
,
last
)
中搜索首个由
count
个相同元素组成的序列,其中每个元素都等于给定的
value
。
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> 为 true 。 |
(C++20 前) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> 为 true 。 |
(C++20 起) |
目录 |
参数
| first, last | - | 定义待检验元素 范围 的迭代器对 |
| count | - | 要搜索的序列长度 |
| value | - | 要搜索的元素值 |
| policy | - | 使用的 执行策略 |
| p | - |
返回
true
当元素应被视为相等的二元谓词
谓词函数的签名应等价于: bool pred ( const Type1 & a, const Type2 & b ) ;
虽然签名不需要包含
const
&
,但函数不得修改传递给它的对象,且必须能够接受所有(可能为const的)
|
| 类型要求 | ||
-
ForwardIt
必须满足
LegacyForwardIterator
的要求。
|
||
-
BinaryPred
必须满足
BinaryPredicate
的要求。
|
||
-
Size
必须可
转换
为
整数类型
。
|
||
返回值
如果
count
为正数,则返回指向范围
[
first
,
last
)
中找到的第一个序列起始位置的迭代器。该序列中的每个迭代器
it
应满足以下条件:
如果未找到这样的序列,则返回 last 。
如果 count 为零或负数,则返回 first 。
复杂度
给定 N 为 std:: distance ( first, last ) :
异常
带有名为
ExecutionPolicy
模板参数的重载按以下方式报告错误:
-
如果作为算法一部分调用的函数执行抛出异常,且
ExecutionPolicy是某个 标准策略 ,则调用 std::terminate 。对于其他任何ExecutionPolicy,其行为由实现定义。 - 如果算法无法分配内存,则抛出 std::bad_alloc 。
可能的实现
| search_n (版本 1) |
|---|
template<class ForwardIt, class Size, class T = typename std::iterator_traits<ForwardIt>::value_type> ForwardIt search_n(ForwardIt first, ForwardIt last, Size count, const T& value) { if (count <= 0) return first; for (; first != last; ++first) { if (!(*first == value)) continue; ForwardIt candidate = first; for (Size cur_count = 1; true; ++cur_count) { if (cur_count >= count) return candidate; // 成功 ++first; if (first == last) return last; // 遍历完列表 if (!(*first == value)) break; // 连续出现次数不足 } } return last; } |
| search_n (版本 3) |
template<class ForwardIt, class Size, class T = typename std::iterator_traits<ForwardIt>::value_type, class BinaryPred> ForwardIt search_n(ForwardIt first, ForwardIt last, Size count, const T& value, BinaryPred p) { if (count <= 0) return first; for (; first != last; ++first) { if (!p(*first, value)) continue; ForwardIt candidate = first; for (Size cur_count = 1; true; ++cur_count) { if (cur_count >= count) return candidate; // 成功 ++first; if (first == last) return last; // 遍历完列表 if (!p(*first, value)) break; // 连续出现次数不足 } } return last; } |
注释
| 功能测试 宏 | 值 | 标准 | 功能 |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type
|
202403
|
(C++26) | 列表初始化 用于算法 ( 1-4 ) |
示例
#include <algorithm> #include <cassert> #include <complex> #include <iostream> #include <iterator> #include <vector> template<class Container, class Size, class T> constexpr bool consecutive_values(const Container& c, Size count, const T& v) { return std::search_n(std::begin(c), std::end(c), count, v) != std::end(c); } int main() { constexpr char sequence[] = ".0_0.000.0_0."; static_assert(consecutive_values(sequence, 3, '0')); for (int n : {4, 3, 2}) std::cout << std::boolalpha << "存在 " << n << " 个连续零: " << consecutive_values(sequence, n, '0') << '\n'; std::vector<std::complex<double>> nums{{4, 2}, {4, 2}, {1, 3}}; #ifdef __cpp_lib_algorithm_default_value_type auto it = std::search_n(nums.cbegin(), nums.cend(), 2, {4, 2}); #else auto it = std::search_n(nums.cbegin(), nums.cend(), 2, std::complex<double>{4, 2}); #endif assert(it == nums.begin()); }
输出:
存在 4 个连续零: false 存在 3 个连续零: true 存在 2 个连续零: true
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 应用于 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 283 | C++98 |
要求
T
满足
EqualityComparable
,但
InputIt
的值类型并不总是
T
|
移除了该要求 |
| LWG 426 | C++98 |
复杂度上限为
N·count
,
当 count 为负数时该值为负 |
当
count
非正时
上限为 0 |
| LWG 714 | C++98 |
若
count
>
0
,复杂度上限为
N·count
,但
最坏情况下的比较/操作次数始终为
N
|
在此情况下将上限
改为
N
|
| LWG 2150 | C++98 | “序列出现”的判定条件有误 | 已修正 |
参见
|
在特定范围内寻找元素的最后序列
(函数模板) |
|
|
(C++11)
|
寻找首个满足特定条件的元素
(函数模板) |
|
搜索元素范围的首次出现
(函数模板) |
|
|
(C++20)
|
在范围内搜索首个连续出现指定次数的元素
(算法函数对象) |