C++ STL算法search(11)

本文详细介绍了C++标准库中用于序列查找的search函数,包括无谓词和谓词版本。通过示例展示了如何在给定序列中查找目标子序列,以及如何使用自定义谓词进行条件查找。示例涵盖了普通函数、仿函数、lambda表达式和bind的使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数原型

//无谓词
//查找 [first1, last1) 范围内第一个 [first2, last2) 子序列
template<class _FwdItHaystack,class _FwdItPat>
_NODISCARD inline _FwdItHaystack search(const _FwdItHaystack _First1, const _FwdItHaystack _Last1, const _FwdItPat _First2, const _FwdItPat _Last2)

//谓词
//查找 [first1, last1) 范围内,和 [first2, last2) 序列满足pred规则的第一个子序列
template<class _FwdItHaystack, class _FwdItPat,class _Pr> 
_NODISCARD inline _FwdItHaystack search(_FwdItHaystack _First1, const _FwdItHaystack _Last1, const _FwdItPat _First2, const _FwdItPat _Last2, _Pr _Pred)

template<class _FwdItHaystack, class _Searcher>
_NODISCARD inline _FwdItHaystack search(const _FwdItHaystack _First, const _FwdItHaystack _Last, const _Searcher& _Search)

 如下两个序列为例:

序列 1:1,2,2,3,4,5,1,2,2,3,4,5

序列 2:1,2,2

用于在序列 1 中查找序列 2 第一次出现的位置。

可以看到,序列 2 在序列 1 中出现了 2 次。借助 find_end() 函数,我们可以找到序列 1 中最后一个(也就是第 2 个){1,2,2};而借助 search() 函数,我们可以找到序列 1 中第 1 个 {1,2,2}。

参数

first1、last1:都为正向迭代器,其组合 [first1, last1) 用于指定查找范围(即序列 1);

first2、last2:都为正向迭代器,其组合 [first2, last2) 用于指定要查找的序列(即序列 2);

pred:自定义查找规则。该规则实际上是一个包含 2 个参数且返回值类型为 bool 的函数(第一个参数接收 [first1, last1) 范围内的元素,第二个参数接收 [first2, last2) 范围内的元素)。函数定义的形式可以是普通函数,也可以是函数对象。

无谓词

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

int main()
{

	std::vector<int> aa{ 1, 2, 2, 3, 4, 5, 1, 2, 2, 3, 4, 5 };
	int arr[] = { 1, 2, 2 };
	auto it = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr));

	if (it == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it) << ", *it = "
			<< *it << '\n';
	}
	std::cout << std::endl;

	return -1;
}

//输出
The first matching elements is at: 0, *it = 1

谓词

 函数

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

bool twice(int a, int b)
{
	std::cout << "a = " << a << "; b = " << b << std::endl;
	return b == a * 2;
}

int main()
{

	std::vector<int> aa{ 1, 2, 2, 3, 4, 5, 2, 4, 4, 3, 4, 5 };
	int arr[] = { 4, 8, 8 };
	auto it = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), twice);

	if (it == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it) << ", *it = "
			<< *it << '\n';
	}
	std::cout << std::endl;

	std::function<bool(int, int)> f = twice;
	auto it1 = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), f);

	if (it1 == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it1) << ", *it = "
			<< *it1 << '\n';
	}
	std::cout << std::endl;

	return -1;
}

//输出
a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

仿函数

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

class Twice
{
public:
	bool operator()(int a, int b)
	{
		std::cout << "a = " << a << "; b = " << b << std::endl;
		return b == a * 2;
	}
};

int main()
{

	std::vector<int> aa{ 1, 2, 2, 3, 4, 5, 2, 4, 4, 3, 4, 5 };
	int arr[] = { 4, 8, 8 };
	auto it = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), Twice());

	if (it == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it) << ", *it = "
			<< *it << '\n';
	}
	std::cout << std::endl;

	return -1;
}

//输出
a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

bind

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

bool twice(int a, int b)
{
	std::cout << "a = " << a << "; b = " << b << std::endl;
	return b == a * 2;
}

class Twice
{
public:
	bool operator()(int a, int b)
	{
		std::cout << "a = " << a << "; b = " << b << std::endl;
		return b == a * 2;
	}
};

int main()
{

	std::vector<int> aa{ 1, 2, 2, 3, 4, 5, 2, 4, 4, 3, 4, 5 };
	int arr[] = { 4, 8, 8 };

	auto f1 = std::bind(twice, std::placeholders::_1, std::placeholders::_2);
	auto it = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), f1);

	if (it == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it) << ", *it = "
			<< *it << '\n';
	}
	std::cout << std::endl;

	auto f2 = std::bind(Twice(), std::placeholders::_1, std::placeholders::_2);
	auto it1 = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), f2);

	if (it1 == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it1) << ", *it = "
			<< *it1 << '\n';
	}

	return -1;
}

//输出
a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

 lambda

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

int main()
{

	std::vector<int> aa{ 1, 2, 2, 3, 4, 5, 2, 4, 4, 3, 4, 5 };
	int arr[] = { 4, 8, 8 };

	auto it = std::search(std::begin(aa), std::end(aa), std::begin(arr), std::end(arr), 
		[](int a, int b) { 
		std::cout << "a = " << a << "; b = " << b << std::endl;
		return b == a * 2; });

	if (it == std::end(aa))
	{
		std::cout << "No matching  elements\n";
	}
	else
	{
		std::cout << "The first matching elements is at: "
			<< std::distance(std::begin(aa), it) << ", *it = "
			<< *it << '\n';
	}
	std::cout << std::endl;

	return -1;
}

//输出
a = 1; b = 4
a = 2; b = 4
a = 2; b = 8
a = 2; b = 4
a = 3; b = 8
a = 3; b = 4
a = 4; b = 4
a = 5; b = 4
a = 2; b = 4
a = 4; b = 8
a = 4; b = 8
The first matching elements is at: 6, *it = 2

<think>好的,用户想了解C++ STL中的算法相关内容,特别是使用教程和示例代码。首先,我需要回顾一下STL算法的基本知识,确保自己理解正确。STL算法主要位于<algorithm>头文件中,还有一些在<numeric>和<functional>里。常见的算法包括排序、查找、遍历、变换等。 接下来,用户可能需要一个结构清晰的回答,分点说明不同类别的算法,并给出示例。比如分类排序算法查找算法、遍历与操作算法、数值处理算法等。每个类别下需要举几个常用的函数,比如sort、find、for_each、transform,然后给出代码示例。 要注意用户提到的系统级指令,比如行内数学表达式用$...$,独立公式用$$...$$,但这里可能数学公式不多,不过如果有涉及数学的地方需要注意格式。另外,需要生成相关问题,放在最后。 还要结合用户提供的引用内容。引用1提到STL容器、算法和迭代器的重要性,引用2提到优化算法的方法,引用4提到了for_each的用法。在回答中需要自然地引用这些内容,比如在讲for_each时引用[^4],在讲优化时引用[^2]。 需要确保代码示例正确,符合C++语法,并且有注释说明。例如,sort的使用需要包含vector和algorithm,使用迭代器范围。transform可能需要使用back_inserter或者预先分配空间。此外,C++11之后的lambda表达式可以用于for_each等算法,这可以增强示例的可读性。 然后,用户可能希望了解如何高效使用这些算法,比如结合lambda或函数对象,或者如何优化性能,如引用2提到的优化技巧。这部分可能需要单独作为使用技巧或注意事项来讲解。 最后,生成的相关问题要围绕STL算法,比如如何选择合适算法、性能优化、与容器结合使用等。确保问题有针对性,能帮助用户进一步学习。 总结回答结构: 1. 引言:介绍STL算法的重要性,引用[^1] 2. 算法分类及示例:分点介绍各类算法,每个类别下几个函数,示例代码 3. 使用技巧:如lambda、迭代器、优化建议,引用和[^4] 4. 注意事项:包含头文件、迭代器有效性等 5. 相关问题 现在需要检查每个示例代码是否正确,比如sort的示例是否正确使用vector和排序,find_if是否使用lambda,transform是否正确应用函数。确保代码没有语法错误,并且注释清晰。 另外,注意回答要使用中文,避免使用Markdown格式,但用户示例中的代码块是用```python,这里应该改为```cpp。但根据用户提供的系统指令,用户不可见部分可能有格式要求,但用户可见层需要结构清晰。不过原示例中的代码块是python,但用户的问题是关于C++,所以需要调整。 最后,在引用处自然添加标识,比如在提到for_each时引用[^4],在优化部分引用[^2],在介绍STL整体时引用[^1]。</think>### C++ STL算法使用教程与示例代码 C++标准模板库(STL)提供了丰富的算法,用于简化数据操作和提升代码效率。这些算法通过迭代器与容器解耦,支持灵活的应用场景。以下是常见算法分类及使用示例: --- #### 一、排序与合并算法 1. **`sort`:快速排序** ```cpp #include <vector> #include <algorithm> std::vector<int> nums = {3, 1, 4, 1, 5, 9}; std::sort(nums.begin(), nums.end()); // 默认升序 // 结果为 {1, 1, 3, 4, 5, 9} ``` 2. **`stable_sort`:稳定排序** 保持相等元素的原始顺序,适用于复杂结构体排序。 --- #### 二、查找与判断算法 1. **`find`:线性查找** ```cpp auto it = std::find(nums.begin(), nums.end(), 4); if (it != nums.end()) { // 找到元素4的位置 } ``` 2. **`binary_search`:二分查找** 需先对容器排序: ```cpp bool exists = std::binary_search(nums.begin(), nums.end(), 5); ``` 3. **`any_of`:条件判断** ```cpp bool has_negative = std::any_of(nums.begin(), nums.end(), [](int x) { return x < 0; }); ``` --- #### 三、遍历与操作算法 1. **`for_each`:遍历元素** 使用lambda表达式操作元素[^4]: ```cpp std::vector<int> vec = {1, 2, 3}; std::for_each(vec.begin(), vec.end(), [](int& x) { x *= 2; // 每个元素翻倍 }); // vec变为 {2, 4, 6} ``` 2. **`transform`:数据转换** 将操作结果写入新容器: ```cpp std::vector<int> source = {1, 2, 3}; std::vector<int> target; std::transform(source.begin(), source.end(), std::back_inserter(target), [](int x) { return x * x; }); // target存储 {1, 4, 9} ``` --- #### 四、数值处理算法 1. **`accumulate`:累加计算** ```cpp #include <numeric> int sum = std::accumulate(vec.begin(), vec.end(), 0); // 求和 ``` 2. **`inner_product`:内积计算** 计算两个向量的点积: ```cpp std::vector<int> a = {1, 2}, b = {3, 4}; int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0); // dot = 1*3 + 2*4 = 11 ``` --- #### 五、使用技巧 1. **结合Lambda表达式** 简化自定义逻辑,如筛选条件或复杂操作。 2. **优先选择高效算法** 例如用`sort`替代冒泡排序,或使用`nth_element`快速找中位数。 3. **注意迭代器有效性** 操作后若容器被修改(如`push_back`),需确保迭代器未失效。 --- #### 六、注意事项 - 包含头文件:`<algorithm>`、`<numeric>`、`<functional>`。 - 输入迭代器范围一般为左闭右开区间 `[begin, end)`。 - 对关联容器(如`std::set`)使用只读算法,避免破坏内部顺序。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值