C++ STL算法系列2---find ,find_first_of , find_if , adjacent_find的使用


一.find運算

假設有一個int型的vector對象,名為vec,我們想知道其中是否包含某個特定值

解決這個問題最簡單的方法時使用標准庫提供的find運算:

 1 // value we'll look for
 2 int search_value = 42;
 3 
 4 //call find to see if that value is present
 5 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value);
 6 
 7 //report the result
 8 cout<<"The value "<<search_value
 9 <<(result == vec.end() ? " is not present" : "is present")
10 <<endl;

具體實現代碼:

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8 // value we'll look for
 9    int search_value = 42;
10    int ival;
11    vector<int> vec;
12 
13    while(cin>>ival)
14       vec.push_back(ival);
15    
16    cin.clear();
17 
18 //call find to see if that value is present
19    vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value);
20 
21 //report the result
22   cout<<"The value "<<search_value
23       <<(result == vec.end() ? " is not present" : "is present")
24       <<endl;
25 
26   return 0;
27 }

 接下來再舉一個例子:

 1 #include <algorithm>  
 2 #include <list>  
 3 #include <iostream>  
 4   
 5 using namespace std;  
 6   
 7 int main()  
 8 {  
 9     list<int> ilist;  
10     for (size_t i = 0; i < 10; ++i)  
11     {  
12         ilist.push_back(i+1);  
13     }  
14   
15     ilist.push_back(10);  
16   
17     list<int>::iterator iLocation = find(ilist.begin(), ilist.end(), 10);   //find操作查找等於10的元素,並返回指向該元素的迭代器,如果沒有找到,返回指向集合最后一個元素的迭代器
18   
19     if (iLocation != ilist.end())  
20     {  
21         cout << "找到元素 10" << endl;  
22     }  
23   
24     cout << "前一個元素為:" << *(--iLocation) << endl;  
25   
26     return 0;  
27 }  

 

類似地,由於指針的行為與作用在內置數組上的迭代器一樣,因此也可以使用find來搜索數組

1 int ia[6] = {27 , 210 , 12 , 47 , 109 , 83};
2 int search_value = 83;
3 int *result = find(ia , ia + 6 , search_value);
4 cout<<"The value "<<search_value
5     <<(result == ia + 6 ? " is not present" : "is present")
6     <<endl;

如果需要傳遞一個子區間,則傳遞指向這個子區間的第一個元素以及最后一個元素的下一位置的迭代器(或指針)。

例如,在下面對find函數的調用中,只搜索了ia[1]和ia[2]:

//only search elements ia[1] and ia[2]
int *result = find(ia + 1 , ia + 3 , search_value);

 

二.find_first_of的使用

除了find之外,標准庫還定義了其他一些更復雜的查找算法。當中的一部分類似string類的find操作,其中一個是find_first_of函數。

這個算法帶有兩對迭代器參數來標記兩端元素范圍:第一段范圍內查找與第二段范圍中任意元素匹配的元素,然后返回一個迭代器,指向第一個匹配的元素。如果找不到匹配元素,則返回第一個范圍的end迭代器。

假設roster1和roster2是兩個存放名字的list對象,可使用find_first_of統計有多少個名字同時出現在這兩個列表中

 1 size_t cnt = 0;
 2 list<string>::iterator it = roster1.begin();
 3 
 4 // look in roster1 for any name also in roster2
 5 while((it = find_first_of(it , roster1.end() , roster2.begin() , roster2.end())) != roster1.end())
 6 {
 7     ++cnt;
 8     // we got a match , increment it to look in the rest of roster1
 9     ++it;
10 }
11 cout<<"Found "<<cnt
12     <<"  names on both rosters "<<endl;

調 用find_first_of查找roster2中的每個元素是否與第一個范圍內的元素匹配,也就是在it到roster1.end()范圍內查找一個元 素。該函數返回此范圍內第一個同時存在於第二個范圍中的元素。在while的第一次循環中,遍歷整個roster1范圍。第二次以及后續的循環迭代則只考 慮roster1中尚未匹配的部分。

循環條件檢查find_first_of的返回值,判斷是否找到匹配的名字。如果找到一個匹配,則使計 數器加1,同時給it加1,使它指向roster1中的下一個元素。很明顯可知,當不再有任何匹配時,find_first_of返回 roster1.end(),完成統計。

find_first_of,帶有兩對迭代器參數。每對迭代器中,兩個參數的類型必須精確匹配,但不要求兩對之間的類型匹配。特別是,元素可存儲在不同類型的序列中,只要這兩個序列的元素可以比較即可。

在 上述程序中,roster1和roster2的類型不必精確匹配:roster1可以使list對象,而roster2則可以使vector對象、 deque對象或者是其他后面要學到的序列。只要這兩個序列的的元素可使用相等(==)操作符進行比較即可。如果roster1是list< string>對象,則roster2可以使vector<char*>對象,因為string標准庫為string對象與char* 對象定義了相等(==)操作符。

 

三.find_if的使用

find_if算法 是find的一個謂詞判斷版本,它利用返回布爾值的謂詞判斷pred,檢查迭代器區間[first, last)上的每一個元素,如果迭代器iter滿足pred(*iter) == true,表示找到元素並返回迭代器值iter;未找到元素,則返回last。

find_if :在序列中找符合某謂詞的第一個元素。

函數原型為:

1     template<class InputIterator, class Predicate>  
2        InputIterator find_if(  
3           InputIterator _First,   
4           InputIterator _Last,   
5           Predicate _Pred  
6        );  

舉個例子說明如下:

 1 #include <algorithm>  
 2 #include <vector>  
 3 #include <iostream>  
 4   
 5 using namespace std;  
 6   
 7 //謂詞判斷函數 divbyfive : 判斷x是否能5整除  
 8 bool divbyfive(int x)  
 9 {  
10     return x % 5 ? 0 : 1;  
11 }  
12   
13 int main()  
14 {  
15   /*  
16     //初始vector : 方式一 
17     //使用下標方式來操作vector
18     //vector隨機訪問方便,但插入、刪除操作效率非常低
19     vector<int> iVect(20);  
20 
21     for(size_t i = 0; i < iVect.size(); ++i)   //注意:size_t
22     {  
23         iVect[i] = (i+1) * (i+3);  
24     }  
25 
26 */
27     //初始vector :方式二
28     vector<int> iVect;
29     for(vector<int>::size_type i = 0 ; i != 20 ; ++i)
30         iVect.push_back((i+1) * (i + 3));
31      
32 
33     //輸出vector里的元素
34     for(vector<int>::iterator iter = iVect.begin() ; iter != iVect.end() ; ++iter)
35         cout<<*iter<<" ";
36     cout<<endl;
37   
38   
39     vector<int>::iterator iLocation;  
40     iLocation = find_if(iVect.begin(), iVect.end(), divbyfive);  
41   
42     if (iLocation != iVect.end())  
43     {  
44         cout << "第一個能被5整除的元素為:"  
45              << *iLocation << endl                  //打印元素:15                 
46              << "元素的索引位置為:"  
47              << iLocation - iVect.begin() << endl;  //打印索引位置:2  
48     }  
49      
50     return 0;  
51 }  

 

四. adjacent_find算法

adjacent_find算法用於查找相等或滿足條件的鄰近元素對。其有兩種函數原型:一種在迭代器區間[first , last)上查找兩個連續的元素相等時,返回元素對中第一個元素的迭代器位置。另一種是使用二元謂詞判斷binary_pred,查找迭代器區間 [first , last)上滿足binary_pred條件的鄰近元素對,未找到則返回last。

原型:

 1 <strong>template<class ForwardIterator>  
 2    ForwardIterator adjacent_find(  
 3       ForwardIterator _First,   
 4       ForwardIterator _Last  
 5       );  
 6 template<class ForwardIterator , class BinaryPredicate>  
 7    ForwardIterator adjacent_find(  
 8       ForwardIterator _First,   
 9       ForwardIterator _Last,   
10             BinaryPredicate _Comp  
11    );  
12 </strong> 

舉例如下:

 1 #include <algorithm>  
 2 #include <list>  
 3 #include <iostream>  
 4   
 5 using namespace std;  
 6   
 7 //判斷X和y是否奇偶同性  
 8 bool parity_equal(int x, int y)  
 9 {  
10     return (x - y) % 2 == 0 ? 1 : 0;  
11 }  
12   
13 int main()  
14 {  
15     //初始化鏈表  
16     list<int> iList;  
17     iList.push_back(3);  
18     iList.push_back(6);  
19     iList.push_back(9);  
20     iList.push_back(11);  
21     iList.push_back(11);  
22     iList.push_back(18);  
23     iList.push_back(20);  
24     iList.push_back(20);  
25   
26     //輸出鏈表  
27     list<int>::iterator iter;  
28     for(iter = iList.begin(); iter != iList.end(); ++iter)  
29     {  
30         cout << *iter << "  ";  
31     }  
32     cout << endl;  
33       
34     //查找鄰接相等的元素  
35     list<int>::iterator iResult = adjacent_find(iList.begin(), iList.end());  
36     if (iResult != iList.end())  
37     {  
38         cout << "鏈表中第一對相等的鄰近元素為:" << endl;  
39         cout << *iResult++ << endl;  
40         cout << *iResult << endl;  
41     }  
42   
43     //查找奇偶性相同的鄰近元素  
44     iResult = adjacent_find(iList.begin(), iList.end(), parity_equal);  
45     if (iResult != iList.end())  
46     {  
47         cout << "鏈表中第一對奇偶相同的元素為:" << endl;  
48         cout << *iResult++ << endl;  
49         cout << *iResult << endl;  
50     }  
51     return 0;  
52 }  

 

總結:

find()            :  在序列中找某個值的第一個出現

find_if()         :    在序列中符合某謂詞的第一個元素

find_first_if     :    在兩個序列中找匹配元素

adjacent_find : 用於查找相等或滿足條件的鄰近元素對

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM