最近是經常使用stl中的map,于是就想記一些關于map的東西。這一篇中會講到map按照value值查找的方法,就是find_if函數。
大家都知道在map中,排序是按照key值排的,map自帶的find方法也是按着key值查找的,這在某些情況下可能會遇到一些麻煩。
譬如,map<int, char*> m_str中,傳入一個char*需要查找在m_str中是否存在這個字元串,當然你大可以使用iterator周遊一些map,
如果你堅持這麼做,那就可以直接關閉網頁了。
1.先來看看find_if的原型:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
template < class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,Predicate pred)
{
while (first != last && !pred(*first)) ++first;
return first;
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
find_if是一個模闆函數,接受兩個資料類型:InputItearator疊代器,Predicate用于比較數值的函數或者函數對象(仿函數)。find_if對疊代器要求很低,隻需要它支援自增操作即可。目前周遊到的記錄符合條件與否,判斷标準就是使得pred()為真。至此可能還有些不是很明了,下面舉幾個例子實際操練下的它的用法。注意觀察第三個參數pred。
2.find_if在std::map查找時的應用
假如我們有個map對象是這麼聲明的:
std::map< int, std:: string> mymap;
mymap.insert(std::make_pair( 20, " USA "));
mymap.insert(std::make_pair( 10, " CHINA "));
mymap.insert(std::make_pair( 30, " English "));
mymap.insert(std::make_pair( 40, " Hongkong ")); 插入值後我們想得到值為”english”的這條記錄,要怎樣寫程式呢?下面是個範例參考下:
#include <map>
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
#include < string>
#include <algorithm>
class map_value_finder
{
public:
map_value_finder( const std:: string &cmp_string):m_s_cmp_string(cmp_string){}
bool operator ()( const std::map< int, std:: string>::value_type &pair)
{
return pair.second == m_s_cmp_string;
}
private:
const std:: string &m_s_cmp_string;
};
int main()
{
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 "));
std::map< int, std:: string>::iterator it = my_map.end();
it = std::find_if(my_map.begin(), my_map.end(), map_value_finder( " English "));
if (it == my_map.end())
printf( " not found\n ");
else
printf( " found key:%d value:%s\n ", it->first, it->second.c_str());
return 0;
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
class map_finder即用于比較的函數對象,它的核心就是重載的()運算符。因為每個容器疊代器的*運算符得到的結果都是該容器的value_type值,是以該運算符的形參就是map疊代器指向的value_type類型的引用。而map的value_type到底是什麼類型,就得看下STL的源代碼是如何定義的。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
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;
......
};
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
從上面的定義可以看出,map的value_type是std::pair<const Key, t>類型,它的first值就是關鍵字,second值儲存map的值域。
3.find_if在vector中的應用與上面的類似,就不舉例子了。 差別就是vecotor的value_type和map的value_type不一樣,想大家應該是明白的。
如果用仿函數,如下:
struct map_value_finder
{
public:
map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}
bool operator ()(const std::map<int, std::string>::value_type &pair)
{
return pair.second == m_s_cmp_string;
}
private:
const std::string &m_s_cmp_string;
};
bool funddd(const std::map<int, std::string>::value_type &pair)
{
return pair.second == "english";
}
int main()
{
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"));
std::map<int, std::string>::iterator it = my_map.end();
it = std::find_if(my_map.begin(), my_map.end(), funddd);
if (it == my_map.end())
printf("not found\n");
else
printf("found key:%d value:%s\n", it->first, it->second.c_str());
getchar();
return 0;
}