1. 程式人生 > >C++ 泛型演算法

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函式,就調換兩個元素的順序。