C++ 泛型演算法
“泛型”指的是演算法可以用於不同型別的元素和多種容器型別,是獨立於容器的。
泛型演算法通過迭代器間接訪問容器,不會執行容器的操作,只執行在迭代器之上,迭代器可以做什麼,泛型演算法就可以做什麼。
標準庫提供了超過100個演算法,但是都有規律可循。大部分都對一個範圍內的元素進行操作,類似於algorithm(vec.begin(),vec.end(),…),前兩個引數確定範圍,後面的引數根據演算法的作用確定。
使用泛型演算法,必須加上標頭檔案
#include<algorithm>
按三個部分介紹:“只讀演算法”、“寫容器元素的演算法”和“重排容器元素的演算法”。
一、只讀演算法
因為是隻讀演算法,不影響容器內的元素,所以遍歷時用cbegin()和cend()。
1. 查詢演算法find
auto result = find(iter1, iter2, val);
查詢兩個迭代器所指範圍內是否存在val,若存在,返回對應元素的迭代器,若不存在,返回第二個引數,在此例中為iter2。
可以以返回值做判斷:
if(result != iter2){//找到了
//```
}
else{}
同樣可用於內建陣列:
int ia[] = {...}; int cal = ...; int* result = find(begin(ia), end(ia), val);
2. 計數演算法count
auto result = count(iter1,iter2,val);
返回兩個迭代器所指範圍內val出現的次數。
3. 求和演算法accumulate
type sum = accumulate(iter1, iter2, val);
返回兩個迭代器所指範圍內所有元素的和,和的初始值設定為val。
和的型別取決於定義的變數型別。
4. 比較演算法equal
bool result = equal(c1.cbegin(),c1.cend(),c2.cbegin());
返回c1和c2兩個序列的大小,前兩個引數是c1序列的始末,第三個引數是c2序列的首元素。
必須保證第二個序列至少和第一個一樣長。
二、寫容器元素演算法
1. 覆蓋演算法fill
fill(iter1, iter2, val);
將兩個迭代器範圍內的所有元素置為val。
fill_n(iter, n, val)
iter開始的序列至少包含n個val元素。
需要注意的是,預設前提是容器必須已經有至少n個元素,若是空的,就不能使用這個演算法,相當於該語句未定義。
2. 插入迭代器back_inserter
在上面覆蓋演算法中,只能覆蓋元素,不能插入,那怎麼插入呢?
back_inserter是插入迭代器,通過此迭代器可以呼叫push_back往容器中新增元素。
fill_n(back_inserter(vec),n,val);
這樣就相當於向vector容器中尾部新增n個val元素。
3. 拷貝演算法copy
auto ret = copy(c1.begin(), c1.end(), c2.begin())
將前兩個迭代器所指範圍內的元素全部拷貝進c2容器中,返回拷貝的最後一個元素之後的位置。
必須保證第二個序列的長度大於第一個序列。
4. 替換演算法replace
replace(iter1, iter2, val1, val2)
將兩個迭代器所指範圍內的val1都替換為val2。
三、重排容器元素的演算法
1. 排序演算法sort
sort(iter1, iter2)
將兩個迭代器所指範圍內的序列升序排列。降序排序的方法在定製操作裡面介紹。
2. 去重演算法unique
auto result = unique(iter1, iter2)
將兩個迭代器所指範圍內相鄰的重複項消除,返回一個指向不重複值範圍末尾的迭代器。
一般在sort排序之後使用。
3. 刪除演算法erase
auto result = erase(iter1,iter2)
將兩個迭代器所指範圍內的元素刪除,返回刪除的最後一個元素之後的迭代器。
四、定製操作
在sort排序演算法中,預設是按升序排列的,這個順序是可以改的。
sort的另一個版本:
sort(itr1, itr2, 布林函式)
當兩個元素比較的時候,就會呼叫這個布林函式。
舉個例子:
bool order(int a, int b){
return a > b;
}
int main()
{
vector<int> v = {1,3,2};
sort(v.begin(),v.end(),order);
}
order函式返回兩個值比較的結果,也就是你想要的結果:降序。
如果sort呼叫order後返回個false,說明不滿足order函式,就調換兩個元素的順序。