簡介
常常需要在vector中查找元素是否存在,或者確定元素的個數。但vector未提供相關的成員函數。
這裏不討論手寫for遍歷的方法。無論從工作量還是效率方面,都應該優先選用STL算法。
注意:對於任意的vector,查找某個元素需要耗費線性時間。除非該vector是有序的。
算法模塊提供了查找的多種方式。
以下代碼需要包含該頭文件。以在vector中查找元素爲例。
方法與示例
1. std::count
對於只需要知道包含特定元素的數量的應用來說,這是最簡單的方式。如果count返回0,則表示不存在該元素。
示例:
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::count;
using std::cout;
using std::endl;
int main()
{
vector<int> v{ 4, 7, 9, 1, 2, 5 };
int key = 2;
if (count(v.begin(), v.end(), key))
{
cout << "Element found" << endl;
}
else
{
cout << "Element NOT found" << endl;
}
return 0;
}
2. std::find
find會在查找到指定值後立即返回,所以它一般比count更快(因爲count總是要遍歷整個容器)。
上述代碼只需要更改條件判斷語句:
if (std::find(v.begin(), v.end(), key) != v.end())
3. std::find_if
它也能完成任務,但有點大材小用了。
find_if需要一個判別式。如果查找的值需要滿足特定的條件時,比如查找小於3且大於1的值時,適合該方式。
如果有多個值符合條件,則返回查找到符合條件的第一個值的迭代器。
條件判斷語句:
if (std::find_if(v.begin(), v.end(), [] (int i) { return i < 3 && i > 1 } ) != v.end())
4. std::any_of(C++11)
與find_if類似,但它返回bool值。
如果判斷式返回true,則它也返回true。否則返回false。
條件判斷語句:
if (std::any_of(v.begin(), v.end(), [] (int i) { return i < 3 && i > 1 } ))
擴展:std::none_of,是any_of的反面。也就是,當判斷式是false時它返回true,否則返回flase。
5. std::binary_search
作爲磨刀不誤砍柴工的一種方式,可以對vector先排序,再查找,就可以使用二分查找了。
二分查找的時間效率爲O(logn)。
代碼片斷:
sort(v.begin(), v.end());
if (std::binary_search(v.begin(), v.end(), key))
小結
方法雖多,側重各不相同。選擇適合的算法有助於提高代碼可讀性和執行效率,簡單總結如下:
- 對於已經排序的vector,使用binary_search
- 僅判斷是否存在某元素,使用find
- 需要某元素總個數時,使用count
- 支持複雜條件的查找時,使用any_of(僅知道是否存在)/find_if(返回了第一個元素的迭代器)