std::find_end - cppreference.com
来自cppreference.com
| 在标头 |
||
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。
复杂度
给定 N1 为 std::distance(first1, last1),N2 为 std::distance(first2, last2):
1) 最多应用 N2⋅(N1-N2+1) 次 operator== 进行比较。
2) 最多应用 N2⋅(N1-N2+1) 次 p。
3) 应用 𝓞(N2⋅(N1-N2+1)) 次 operator== 进行比较。
4) 应用 𝓞(N2⋅(N1-N2+1)) 次 p。
异常
可能的实现
| 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) |