概述
目录
- 一 概述
- 二 辅助函数
- 二 std::find
- 三 std::find_if
- 四 std::find_if_not
- 五 std::search_n
- 六 std::search
- 七 std::find_end
- 八 std::find_first_of
- 九 std::adjacent_find
- 十 说明
一 概述
- C++ 标准库中提供了很多算法,定义于头文件 < algorithm >。本文主要探究以下用于 查找元素 的算法:
- std::find 查找第一个匹配元素
- std::find_if 查找第一个匹配元素
- std::find_if_not(C++11) 查找第一个不匹配元素
- std::search_n 查找前n个连续匹配值
- std::search 查找第一个子区间
- std::find_end 查找最后一个子区间
- std::find_first_of 查找某些元素第一次出现位置
- std::adjacent_find 查找两个连续且相等的元素
二 辅助函数
- 为了举例说明各算法,Demo中定义了如下一些辅助函数:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <list>
#include <functional>
template <typename C>
void fill(C& container, int begin, int end) {
for (auto i = begin; i <= end; i++) {
container.emplace_back(i);
}
}
template <typename C>
void print(const std::string& pre, C container) {
std::cout << pre;
std::copy(container.begin(), container.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
bool even(int a) {
return a % 2 == 0;
}
bool my_equal(int a, int b) {
return a == b;
}
二 std::find
- 定义
- 可参考此前文章 std::find std::execution
- Demo
std::vector<int> vc;
vc.emplace_back(1);
fill(vc, 1, 9);
print("vc: ", vc);
auto it = std::find(vc.begin(), vc.end(), 1);
std::cout << "the first element equals 1 is No."
<< std::distance(vc.begin(), it) << std::endl;
auto it1 = std::find(vc.begin(), vc.end(), 10);
if (it1 != vc.end()) {
std::cout << "the first element equals 10 is No."
<< std::distance(vc.begin(), it1) << std::endl;
} else {
std::cout << "no element equals 10 in vc." << std::endl;
}
- 结果
vc: 1 1 2 3 4 5 6 7 8 9
the first element equals 1 is No.0
no element equals 10 in vc.
- 说明
- std::find 选择容器中第一个匹配元素,若找到则返回指向该元素的迭代器,否则,返回容器 end()。
- std::find 注意其中一个构造函数中 模板参数 ExecutionPolicy, 定义于C++17, 例子请参考此前文章 std::find std::execution
- std::distance 请参考此前文章 C++ iterator(1) 几个辅助函数
三 std::find_if
- 定义
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );(1)(C++20 前)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );(2)(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt find_if( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
UnaryPredicate p );(3)(C++17 起)
- 功能
- 查找第一个 使 UnaryPredicate p 返回 true 的元素
- Demo
print("vc: ", vc);
auto it = std::find_if(vc.begin(), vc.end(), even);
std::cout << "the first even element is No."
<< std::distance(vc.begin(), it) << std::endl;
- 结果
vc: 1 1 2 3 4 5 6 7 8 9
the first even element is No.2
四 std::find_if_not
- 定义
template< class InputIt, class UnaryPredicate >
InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );(1)(C++11 起)(C++20 前)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );(2)(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt find_if_not( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
UnaryPredicate q );(3)(C++17 起)
- 功能
- 查找第一个 使 UnaryPredicate p 返回 false 的元素
- Demo
print("vc: ", vc);
auto it = std::find_if_not(vc.begin(), vc.end(), even);
std::cout << "the first odd element is No."
<< std::distance(vc.begin(), it) << std::endl;
- 结果
vc: 1 1 2 3 4 5 6 7 8 9
the first odd element is No.0
五 std::search_n
- 定义
template< class ForwardIt, class Size, class T >
ForwardIt search_n( ForwardIt first, ForwardIt last, Size count, const T& value );(C++20 前)
template< class ForwardIt, class Size, class T >
constexpr ForwardIt search_n( ForwardIt first, ForwardIt last, Size count, const T& value );(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class Size, class T >
ForwardIt search_n( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, Size count, const T& value );(C++17 起)
template< class ForwardIt, class Size, class T, class BinaryPredicate >
ForwardIt search_n( ForwardIt first, ForwardIt last, Size count, const T& value, BinaryPredicate p );(C++20 前)
template< class ForwardIt, class Size, class T, class BinaryPredicate >
constexpr ForwardIt search_n( ForwardIt first, ForwardIt last, Size count, const T& value,
BinaryPredicate p );(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class Size, class T, class BinaryPredicate >
ForwardIt search_n( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, Size count, const T& value,
BinaryPredicate p );(C++17 起)
- 功能
- 查找前n个连续匹配值
- Demo
print("vc: ", vc);
auto it = std::search_n(vc.begin(), vc.end(), 2, 1);
std::cout << "2
consecutive element equal 1 start at No."
<< std::distance(vc.begin(), it) << std::endl;
// 由于不在早期的STL规范中,所以是binary predicate 而不是unary predicate
auto it1 = std::search_n(vc.begin(), vc.end(), 2, 1, my_equal);
std::cout << "2
consecutive element equal 1 start at No."
<< std::distance(vc.begin(), it1) << std::endl;
- 结果
2
consecutive element equal 1 start at No.0
2
consecutive element equal 1 start at No.0
- 说明
- 关于predicate 可参考 此前文章 C++ predicate
六 std::search
- 定义
template< class ForwardIt1, class ForwardIt2 >
ForwardIt1 search( ForwardIt1 first, ForwardIt1 last, ForwardIt2 s_first, ForwardIt2 s_last );(C++20 前)
template< class ForwardIt1, class ForwardIt2 >
constexpr ForwardIt1 search( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last );(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt1 search( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last );(C++17 起)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >
ForwardIt1 search( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++20 前)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >
constexpr ForwardIt1 search( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPredicate >
ForwardIt1 search( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++17 起)
template<class ForwardIt, class Searcher>
ForwardIt search( ForwardIt first, ForwardIt last, const Searcher& searcher );(C++17 起)(C++20 前)
template<class ForwardIt, class Searcher>
constexpr ForwardIt search( ForwardIt first, ForwardIt last, const Searcher& searcher );(C++20 起)
- 功能
- 查找第一个子区间
- Demo
print("vc: ", vc);
std::list<int> l;
fill(l, 3, 6);
print("list: ", l);
auto it = std::search(vc.begin(), vc.end(), l.begin(), l.end());
std::cout << "the first 3 4 5 6 position in vc is No."
<< std::distance(vc.begin(), it) << std::endl;
// 注意构造函数参数 searcher
//
auto it1 = std::search(vc.begin(), vc.end(),
//
std::boyer_moore_searcher(l.begin(), l.end()) );
//
std::cout << "the 3 4 5 6 position in vc is No."
//
<< std::distance(vc.begin(), it1) << std::endl;
- 结果:
vc: 1 1 2 3 4 5 6 7 8 9
list: 3 4 5 6
the first 3 4 5 6 position in vc is No.3
- 说明
- 模板参数 Searcher (C++17) , 标准库提供以下搜索器
- default_searcher (C++17) 标准 C++ 库搜索算法实现(类模板)
- boyer_moore_searcher(C++17) Boyer-Moore 搜索算法实现(类模板)
- boyer_moore_horspool_searcher(C++17) Boyer-Moore-Horspool 搜索算法实现(类模板)
- 模板参数 Searcher (C++17) , 标准库提供以下搜索器
七 std::find_end
- 定义
template< class ForwardIt1, class ForwardIt2 >
ForwardIt1 find_end( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last );(C++20 前)
template< class ForwardIt1, class ForwardIt2 >
constexpr ForwardIt1 find_end( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last );(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt1 find_end( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last );(C++17 起)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >
ForwardIt1 find_end( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++20 前)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >
constexpr ForwardIt1 find_end( ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPredicate >
ForwardIt1 find_end( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last, BinaryPredicate p );(C++17 起)
- 功能
- 查找最后一个子区间
- Demo
// find_end 查找最后一个子区间 (叫做search_end更合适)
fill(vc, 3, 6);
std::list<int> l;
fill(l, 3, 6);
print("vc: ", vc);
print("list: ", l);
auto it = std::find_end(vc.begin(), vc.end(), l.begin(), l.end());
std::cout << "the last 3 4 5 6 position in vc is No."
<< std::distance(vc.begin(), it) << std::endl;
- 结果
vc: 1 1 2 3 4 5 6 7 8 9 3 4 5 6
list: 3 4 5 6
the last 3 4 5 6 position in vc is No.10
- 说明
- 由于该算法不是早期STL的一部分,被命名为了find_end, 叫做search_end更合适(search 查找第一个子区间)
八 std::find_first_of
- 定义
- 与 find_end 形式类似
- 功能
- 查找某些元素第一次出现位置, 与search 功能类似。可将 find_end 与之对应。
- Demo
std::list<int> l;
fill(l, 3, 6);
print("vc: ", vc);
print("list: ", l);
auto it = std::find_first_of(vc.begin(), vc.end(), l.begin(), l.end());
std::cout << "the first 3 4 5 6 position in vc is No."
<< std::distance(vc.begin(), it) << std::endl;
- 结果
vc: 1 1 2 3 4 5 6 7 8 9 3 4 5 6
list: 3 4 5 6
the first 3 4 5 6 position in vc is No.3
九 std::adjacent_find
- 定义
template< class ForwardIt >
ForwardIt adjacent_find( ForwardIt first, ForwardIt last );(1)(C++20 前)
template< class ForwardIt >
constexpr ForwardIt adjacent_find( ForwardIt first, ForwardIt last );(1)(C++20 起)
template< class ExecutionPolicy, class ForwardIt >
ForwardIt adjacent_find( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last );(2)(C++17 起)
template< class ForwardIt, class BinaryPredicate>
ForwardIt adjacent_find( ForwardIt first, ForwardIt last, BinaryPredicate p );(3)(C++20 前)
template< class ForwardIt, class BinaryPredicate>
constexpr ForwardIt adjacent_find( ForwardIt first, ForwardIt last, BinaryPredicate p );(3)(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class BinaryPredicate>
ForwardIt adjacent_find( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, BinaryPredicate p );(4)(C++17 起)
- 功能
- 查找两个连续且相等的元素
- Demo
std::list<int> l;
fill(l, 3, 6);
fill(l, 6, 7);
fill(l, 7, 8);
print("list: ", l);
auto it = std::adjacent_find(l.begin(), l.end());
std::cout
<< "the first two same consecutive element position in list is No."
<< std::distance(l.begin(), it) << std::endl;
- 结果
list: 3 4 5 6 6 7 7 8
the first two same consecutive element position in list is No.3
十 说明
- 由于一些算法早期不在标准库中,一些命名和参数类型并不符合通用规范, 例如
- search_n 使用 binary predicate 而不是 unary predicate。
- find_end 使用 forward_iterator 而不是 input_iterator等。
- iterator 可参考此前文章 C++ iterator(4) Tag & Traits
- C++17 增加一些新的算法的构造函数模板参数,例如
- std::find ExecutionPolicy模板参数
- std::search Searcher模板参数
- 参考
- 《C++ 标准库 第2版》
- cppreference
最后
以上就是直率舞蹈为你收集整理的C++ 算法 查找元素的全部内容,希望文章能够帮你解决C++ 算法 查找元素所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复