来自cppreference.com
| 在标头 <algorithm> 定义
|
||
template< class ForwardIt1, class ForwardIt2 >
ForwardIt1 find_end( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2 );
|
(1) | (C++20 起为 constexpr) |
template< class ForwardIt1, class ForwardIt2, class BinaryPred >
ForwardIt1 find_end( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
BinaryPred p );
|
(2) | (C++20 起为 constexpr) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt1 find_end( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2 );
|
(3) | (C++17 起) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class BinaryPred >
ForwardIt1 find_end( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
BinaryPred p );
|
(4) | (C++17 起) |
在源范围 [first1, last1) 中搜索目标范围 [first2, last2) 最后一次出现的位置。
1) 用
operator== 比较元素。2) 用给定的二元谓词
p 比较元素。3,4) 同 (1,3),但按照
policy 执行。 这些重载只有在以下表达式的值是
true 时才会参与重载决议:
|
|
(C++20 前) |
|
|
(C++20 起) |
参数
| first1, last1 | - | 表示源范围的迭代器对 |
| first2, last2 | - | 表示目标范围的迭代器对 |
| p | - | 若元素应被当做相等则返回 true 的二元谓词谓词函数的签名应等价于如下:
虽然签名不必有 |
| policy | - | 所用的执行策略 |
| 类型要求 | ||
-ForwardIt1 必须满足老式向前迭代器 (LegacyForwardIterator) 。
| ||
-ForwardIt2 必须满足老式向前迭代器 (LegacyForwardIterator) 。
| ||
返回值
指向源范围中最后一次出现目标范围处的起始的迭代器。
如果目标范围为空或没有在源范围中出现,那么就会返回 last1。
复杂度
给定 \(\scriptsize N_1\)N1 为 std::distance(first1, last1),\(\scriptsize N_2\)N2 为 std::distance(first2, last2):
1) 最多应用 \(\scriptsize N_2\cdot(N_1-N_2+1)\)N2⋅(N1-N2+1) 次
operator== 进行比较。2) 最多应用 \(\scriptsize N_2\cdot(N_1-N_2+1)\)N2⋅(N1-N2+1) 次
p。3) 应用 \(\scriptsize \mathcal{O}(N_2\cdot(N_1-N_2+1))\)𝓞(N2⋅(N1-N2+1)) 次
operator== 进行比较。4) 应用 \(\scriptsize \mathcal{O}(N_2\cdot(N_1-N_2+1))\)𝓞(N2⋅(N1-N2+1)) 次
p。异常
3,4) 在执行过程中:
- 如果并行化所需的临时内存资源不可用,那么就会抛出 std::bad_alloc。
- 如果在通过算法实参访问对象时抛出了未捕获的异常,那么行为由执行策略决定(标准策略会调用 std::terminate)。
可能的实现
| find_end (1) |
|---|
template<class ForwardIt1, class ForwardIt2>
constexpr //< C++20 起
ForwardIt1 find_end(ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2)
{
if (first2 == last2)
return last1;
ForwardIt1 result = last1;
while (true)
{
ForwardIt1 new_result = std::search(first1, last1, first2, last2);
if (new_result == last1)
break;
else
{
result = new_result;
first1 = result;
++first1;
}
}
return result;
}
|
| find_end (2) |
template<class ForwardIt1, class ForwardIt2, class BinaryPred>
constexpr //< C++20 起
ForwardIt1 find_end(ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2, BinaryPred p)
{
if (first2== last2)
return last1;
ForwardIt1 result = last1;
while (true)
{
ForwardIt1 new_result = std::search(first1, last1, first2, first2, p);
if (new_result == last1)
break;
else
{
result = new_result;
first1 = result;
++first1;
}
}
return result;
}
|
示例
运行此代码
#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
auto print_result = [](auto result, const auto& v)
{
result == v.end()
? std::cout << "未找到序列\n"
: std::cout << "最后一次在位置 " << std::distance(v.begin(), result)
<< " 出现\n";
};
int main()
{
const auto v = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
for (const auto& x : {std::array{1, 2, 3}, {4, 5, 6}})
{
auto iter = std::find_end(v.begin(), v.end(), x.begin(), x.end()); // 重载 (1)
print_result(iter, v);
}
for (const auto& x : {std::array{-1, -2, -3}, {-4, -5, -6}})
{
auto iter = std::find_end(v.begin(), v.end(), x.begin(), x.end(), // 重载 (3)
[](int x, int y)
{
return std::abs(x) == std::abs(y);
});
print_result(iter, v);
}
}
输出:
最后一次在位置 8 出现
未找到序列
最后一次在位置 8 出现
未找到序列
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 1205 | C++98 | 目标范围为空时返回值不明确 | 此时会返回 last1
|
| LWG 2150 | C++98 | “出现”的条件不正确 | 已改正 |
参阅
(C++20) |
查找元素序列在特定范围中最后一次出现 (算法函数对象) |
| 搜索元素范围的首次出现 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 判断一个序列是否为另一个序列的子序列 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 查找首对相同(或满足给定谓词)的相邻元素 (函数模板 & 算法函数对象) | |
(C++20) |
|
(C++11) |
查找首个满足特定条件的元素 (函数模板 & 算法函数对象) |
(C++20)(C++20)(C++20) |
|
| 搜索一组元素中任一元素 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 搜索元素在范围中首次连续若干次出现 (函数模板 & 算法函数对象) | |
(C++20) |