泛型算法之 find、find_if 与 find_if_not

本文深入解析C++标准模板库中的find函数,包括find、find_if和find_if_not三种形式,探讨其线性复杂度及应用案例。通过具体代码示例,展示如何在向量中查找特定值或满足条件的第一个元素,以及为何在已排序数据中应选择更高效的算法。

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

  1. InputIterator find (InputIterator beg, InputIterator end, const T& value);
  2. InputIterator find_if (InputIterator beg, InputIterator end, UnaryPredicate op);
  3. InputIterator find_if_not (InputIterator beg, InputIterator end, UnaryPredicate op);

find函数共有上面三种形式,这三种形式都是对于区间元素逐个比较,直到找到符合条件的元素,所以该函数是线性复杂度,第一种返回的是区间中第一个等于value元素的位置,第二个返回第一个令op返回true的位置,第三种形式返回的是第一个令op返回false的位置,如果没有找到符合规则的元素,这三种形式都将返回end。

注意:

  1. op不应该改变区间内的元素。
  2. 运行期间op的状态不应该被改变。
  3. 并联容器以及无序容许内部提供一个名为find()的成员函数,对于提供find函数的容器我们应该尽量使用成员函数,因为成员函数中的find一般有更好的效率,例如map中的find则是对数复杂度,而std::find的复杂度是线性的,
  4. 对于已排序的应该采用lower_bound,upper_bound(), equal_range(),或者binary_search()算法,(对于这几个算法我们后面介绍)。

请看下面这个例子:

#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;

int main()
{
	vector<int>v1{ 1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1 };
	auto it1 = find(v1.begin(), v1.end(), 2);
	decltype(it1) it2;

	if (it1 != v1.end())
	{
		it2 = find(++it1, v1.end(), 2);
	}
	if (it1!=v1.end() && it2 != v1.end())
	{
		copy(--it1, ++it2, ostream_iterator<int>(cout, " "));
		cout << endl;
	}

    return 0;
}
输出结果:2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 

其中有一点我们需要注意一下,那就是为什么copy(--it1, ++it2, ostream_iterator<int>(cout, " "));这样输出的结果是2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 ,这是因为我们的copy算法对区间的操作是左闭右开,所以这里打印的结果并没有错。

我们再看第二个例子:

int main()
{
    vector<int>v1{ 1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1 };

    auto it1 = find_if(v1.begin(), v1.end(), std::bind(std::greater<int>(),std::placeholders::_1,3));
    auto it2 = find_if_not(v1.begin(), v1.end(), [](int n)
    {
	return  n < 8;
    });

    cout << *it1 << ends << *it2;
    return 0;
}

输出结果:4 8

这里我们第一种情况使用的是函数对象,查找的是一个大于3的值所以结果是4,对于find_if_not我们查找的是第一个>=8的值因此是8.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值