stl.find_if用法總結

轉自:http://www.cnblogs.com/motadou/archive/2009/02/01/1561549.html

有時我們要在map、vector容器中查找符合條件的記錄,map提供一個find的成員函數,但也僅限於查找關鍵字滿足條件的記錄,不支持值域的比較。如果我們要在值域中查找記錄,該函數就無能無力了。而vector甚至連這樣的成員函數都沒有提供。所以一般情況下進行值域的查找,要麼自己遍歷數據,要麼求助於STL的find_if函數。前種方法我們這裏就不贅述了,只講find_if函數。

1 -- find_if的STL定義

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

find_if是一個模板函數,接受兩個數據類型:InputItearator迭代器,Predicate用於比較數值的函數或者函數對象(仿函數)。find_if對迭代器要求很低,只需要它支持自增操作即可。當前遍歷到的記錄符合條件與否,判斷標準就是使得pred()爲真。至此可能還有些不是很明瞭,下面舉幾個例子實際操練下的它的用法。

2 -- find_if在std::map查找時的應用

假如我們有個map對象是這麼聲明的:

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

 

插入值後我們想得到值爲”english”的這條記錄,要怎樣寫程序呢?下面是個範例參考下:

#include <map>
#include <string>
 
class map_finder
{
public:
       map_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}
       bool operator ()(const std::map<int, std::string>::value_type &pair)
       {
10              return pair.second == m_s_cmp_string;
11         }
12  private:
13          const std::string &m_s_cmp_string;                    
14  };
15   
16  int main()
17  {
18      std::map<int, std::string> my_map;
19      my_map.insert(std::make_pair(10, "china"));
20      my_map.insert(std::make_pair(20, "usa"));
21      my_map.insert(std::make_pair(30, "english"));
22      my_map.insert(std::make_pair(40, "hongkong"));    
23      
24      std::map<int, std::string>::iterator it = my_map.end();
25      it = std::find_if(my_map.begin(), my_map.end(), map_finder("english"));
26      if (it == my_map.end())
27         printf("not found\n");       
28      else
29         printf("found key:%d value:%s\n", it->first, it->second.c_str());
30         
31      return 0;        
32  }

class map_finder即用於比較的函數對象,它的核心就是重載的()運算符。因爲每個容器迭代器的*運算符得到的結果都是該容器的value_type值,所以該運算符的形參就是map迭代器指向的value_type類型的引用。而map的value_type到底是什麼類型,就得看下STL的源代碼是如何定義的。

template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
class map
{
public:
typedef Key key_type;
typedef pair<const Key, T> value_type;
......
};

從上面的定義可以看出,map的value_type是std::pair<const Key, t>類型,它的first值就是關鍵字,second值保存map的值域。

3 -- find_if在std::vector的應用

vector的find_if用法與map的很相似,區別僅僅是二者的value_type不一樣而已。我們看下vecotr對value_type的定義。

template <class T, class Alloc = alloc>
class vector
{
public:
typedef T value_type;
typedef value_type* iterator;
......
};

可以看出vector的value_type就是容器的值類型,瞭解了這點,我們做個vector的find_if示範。

#include <vector>
#include <string>
 
struct value_t
{
    int a;
    int b;
};
 
10  class vector_finder
11  {
12  public:
13      vector_finder(const int a):m_i_a(a){}
14      bool operator ()(const std::vector<struct value_t>::value_type &value)
15      {
16          return value.a == m_i_a;
17      }
18  private:
19      int m_i_a;                    
20  };
21   
22   
23  int main()
24  {
25      std::vector<struct value_t> my_vector;
26      struct value_t my_value;
27     
28      my_value.a = 11; my_value.b = 1000;
29      my_vector.push_back(my_value);
30      
31      my_value.a = 12; my_value.b = 1000;
32      my_vector.push_back(my_value);
33   
34      my_value.a = 13; my_value.b = 1000;
35      my_vector.push_back(my_value);
36   
37      my_value.a = 14; my_value.b = 1000;
38      my_vector.push_back(my_value);
39      
40      std::vector<struct value_t>::iterator it = my_vector.end();
41      it = std::find_if(my_vector.begin(), my_vector.end(), vector_finder(13));
42      if (it == my_vector.end())
43         printf("not found\n");       
44      else
45         printf("found value.a:%d value.b:%d\n", it->a, it->b);
46         
47      getchar();
48      return 0;        
49 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章