C++ 中STL中的for_each()、find_if函数

与STL对应的有很多算法,《c++ primer》中叫做泛型算法,比如常用的find(),find_if(),accumulate()等,均为泛型算法。以下针对for_each()、find_if函数的使用进行相应的介绍。

目录

for_each()用法

find_if()用法


一、for_each():

for_each的原型声明如下

template Function for_each (InputIterator first,InputIterator last, Function fn)
for_each()也是一个模板函数。(关于模板函数可以参考《c++高级编程》,《c++ template》,这两本书确实是好书。)第一个参数为迭代器的开始位置,第二个参数为迭代器的末位,也就是迭代器最后一位的下一位。第三个参数为一个函数指针,或者函数对象。
#include <map>
#include <string>
#include <utility>
using namespace std;

void printPair(const pair<int,int> & elem)
{
	cout << "fn为函数指针:"<< elem.first << " " << elem.second << endl;
}

class CprintPair
{
public:
	void operator()(const pair<int,int> & elem)
	{
		cout << "fn为函数对象:" << elem.first << " " << elem.second << endl;
	}
};
int main()
{
	map<int,int> myMap;
	myMap.insert(make_pair(1, 10));
	myMap.insert(make_pair(2, 20));
	myMap.insert(make_pair(3, 30));

	for_each(myMap.begin(), myMap.end(), printPair);//fn为函数指针
	for_each(myMap.begin(), myMap.end(), CprintPair());//fn为函数对象
	system("pause");
	return 0;
}

//输出:
//fn为函数指针:1 10
//fn为函数指针:2 20
//fn为函数指针:3 30
//fn为函数对象:1 10
//fn为函数对象:2 20
//fn为函数对象:3 30

二、find_if():接收一个函数对象的参数作为参数, 并使用它来做更复杂的评价对象是否和给出的查找条件相符。

for_if()的原型声明如下:

template<class InputIterator, class Predicate>
  InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
  {
    for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
    return first;
  }

在区间[first,end)中搜寻使一元判断式pred为true的第一个元素,如果没找到,返回end。

1)假设我们的list中有一些按年代排列的包含了事件和日期的记录。我们希望找出发生在1997年的事件。

代码如下:

#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;

class EventIsIn1997 {
public: 
	bool operator () (string& EventRecord) {
		// year field is at position 12 for 4 characters in EventRecord
		return EventRecord.substr(11,4)=="1997";
		//return this->substr(11,4)=="1997"
	}
};

int main (void) {
	list<string> Events;

	// string positions 0123456789012345678901234567890123456789012345
	Events.push_back("07 January 1995 Draft plan of house prepared");
	Events.push_back("07 February 1996 Detailed plan of house prepared");
	Events.push_back("10 January 1997 Client agrees to job");
	Events.push_back("15 January 1997 Builder starts work on bedroom");
	Events.push_back("30 April 1997 Builder finishes work");

	list<string>::iterator EventIterator = find_if (Events.begin(), Events.end(), EventIsIn1997());

	// find_if completes the first time EventIsIn1997()() returns true
	// for any object. It returns an iterator to that object which we
	// can dereference to get the object, or if EventIsIn1997()() never
	// returned true, find_if returns end()
	if (EventIterator==Events.end()) {
		cout << "Event not found in list" << endl;
	}
	else {
		cout << *EventIterator << endl;
	}
}

//输出:
//10 January 1997 Client agrees to job

注意,find_if()的第三个参数是EventIsIn1997(),它是个仿函数,接收一个string对象,在运算符()的内部定义我所要的查找条件,本例的查找条件是:EventRecord.substr(11,4)=="1997",注意,这里的仿函数返回类型必须是bool类型,这客观反应在find_if()函数查找过程中的是否匹配!

2)数据类型是自定义的结构体的查找过程:

代码:

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

struct value_t
{
	int a;
	int b;
};

class vector_finder
{
public:
	vector_finder( const int a, const int b ) :m_v_a(a),m_v_b(b){}
	bool operator ()( vector<struct value_t>::value_type &value)
	{
		return (value.a==m_v_a)&&(value.b = m_v_b);
	}
private:
	int m_v_a;
	int m_v_b;
};

int main()
{
	vector<value_t> my_vector;
	value_t my_value;

	my_value.a = 11; my_value.b = 1001;
	my_vector.push_back(my_value);

	my_value.a = 12; my_value.b = 1002;
	my_vector.push_back(my_value);

	my_value.a = 13; my_value.b = 1003;
	my_vector.push_back(my_value);

	my_value.a = 14; my_value.b = 1004;
	my_vector.push_back(my_value);

	vector<value_t>::iterator it = find_if( my_vector.begin(), my_vector.end(), vector_finder(13,1003));
	if( it == my_vector.end() )
		cout<<"not found!"<<endl;
	else
		cout<<"found value a:"<<(*it).a <<", b:"<<(*it).b<<endl;
	return 0;
}
//输出:
//found value a:13, b:1003

在这里,我们同样构造了一个仿函数,也就是class vector_finder,也就是vector_finder()函数,注意它的结构与我们要查找的结构体之间的关系,我们发现,它们是非常相象的。

这里的重点就在于class vector_finder的构造!

3)在map容器中的应用

代码:

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

class map_finder
{
public:
	map_finder( string cmp_string ) : m_string(cmp_string) {}
	bool operator () (const map<int,string>::value_type pair)
	{
		return pair.second == m_string;
	}
private:
	string m_string;
};

int main()
{
	map<int ,string> my_map;
	my_map.insert( make_pair(10,"china"));
	my_map.insert( make_pair(20,"usa"));
	my_map.insert( make_pair(30,"english"));
	my_map.insert( make_pair(40,"hongkong"));

	map<int,string>::iterator it = find_if(my_map.begin(),my_map.end(),map_finder("english"));
	if( it == my_map.end() )
		cout<<"not found!"<<endl;
	else
		cout<<"found key:"<<(*it).first<<", value:"<<(*it).second<<endl;
	return 0;
}

//输出:
//found key:30,vlaue:english

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值