概述
標頭檔案algorithm(演算法庫)中主要提供了一些對容器操作的函式,如排序、搜尋、複製、比較等,因此使用頻率還是很高的,由於主要是操作容器,所以函式的語法也很類似:
algorithm_name(container.begin(), container.end(), ...);
其中,container.begin()和container.end()分別表示指向容器開頭和結尾的迭代器,對於陣列來說,則是陣列的首地址和尾地址(當然,不一定非得是首和尾,也可以是中間的某個範圍)
1. 排序sort
sort函式可以對容器進行排序,其基本語法為
sort(container.begin(), container.end(), compare_function);
例如:
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {2,1,4,3,5}; sort(a,a+5); for(int i:a){ cout<<i<<endl; } }
// 輸出為 1 2 3 4 5
也可以對陣列中的某一部分進行排序:
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {2,1,4,3,5}; //注意這個地址區間是左閉右開的 sort(a+2,a+5); for(int i:a){ cout<<i<<endl; } }
// 輸出為2 1 3 4 5
除此之外,sort還支援傳入一個回撥函式作為引數來自定義比較規則,該函式在自定義時,最好定義返回型別為bool,兩個形參,表示比較的雙方。例如,sort預設是升序排列的,我們可以透過改變比較規則來實現降序排列的效果:
#include <iostream> #include <algorithm> using namespace std;
// 自定義比較規則函式 bool f(int i,int j){ return i>j; } int main() { int a[5] = {2,1,4,3,5}; sort(a,a+5,f); for(int i:a){ cout<<i<<endl; } }
// 輸出結果為5 4 3 2 1
2. 查詢find
find可用於在容器指定範圍內查詢元素,若能找到,則返回第一個匹配的元素指標,若不能找到,將固定返回container.end()。作用和python中的關鍵字in比較類似,但用法差異較大。其基本語法為:
auto it = find(container.begin(), container.end(), value);
基本的用法:
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {2,1,4,3,5}; //這裡注意返回的是一個指標,同樣可以指定查詢的範圍 int* index = find(a,a+5,3); //這裡能找到,所以將輸出3,若不能找到,*index會固定輸出引數值,但index始終是陣列的末尾指標 cout<<*index; }
find常用於判斷某個元素是否存在於容器中:
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {2,1,4,3,5}; int* index = find(a,a+5,6); if(index!=a+5){ cout<<"該元素在陣列中"<<endl; } else{ cout<<"該元素不在陣列中"<<endl; } } // 輸出結果為: 該元素不在陣列中
3. 複製copy
copy用於將容器中指定範圍內的元素複製到另一個容器中,這裡的複製是淺複製,也就是隻複製值,不複製引用,其基本語法為:
copy(source_begin, source_end, destination_begin);
source表示源容器,destination表示目標容器
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {2,1,4,3,5}; int b[8] = {1,1,1,1,1,1,1,1}; /** 複製的時候要注意: 若源資料的個數多於b的容量,則會報錯 若源資料的個數小於等於b的容量,則會從b的頭部開始替換元素 **/ copy(a,a+5,b); for(int i:b){ cout<<i<<" "; } } // 輸出結果為:2 1 4 3 5 1 1 1
需要注意的是,像陣列和vector這種不同的資料結構,因為底層的儲存邏輯是有區別的,所以不能相互複製。
4. 比較equal
如果有兩個陣列,a[5]={1,2,3,4,5},b[5]={1,2,3,4,5},如果我們想判斷這兩個陣列中的元素是否相等,直接寫a==b當然是不行的,因為這樣比較的是兩個陣列的地址,結果一定是假。如果要比較兩個容器中或兩個範圍內的元素是否相等,就需要使用equal函式,其基本語法為:
bool result = equal(first1, last1, first2, compare_function);
仔細觀察可以發現,沒有傳第二個範圍的終止值,因為這裡會自動地取和第一個範圍相同的長度。
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {1,2,3,4,5}; int b[5] = {1,2,3,4,5}; //cout<<(a==b)輸出結果是0 bool result = equal(a,a+5,b); cout<<result<<endl; } // 輸出結果為1
既然在用法中說明了,可以用於兩個範圍,所以也可以判斷同一個容器中兩個範圍內的元素是否相等
#include <iostream> #include <algorithm> using namespace std; int main() { int a[6] = {1,2,3,1,2,3}; bool result = equal(a,a+3,a+3); cout<<result<<endl; } // 輸出結果仍然為1
注意到,和sort一樣,equal函式也支援傳入一個回撥函式,用於自定義“相等”的規則
#include <iostream> #include <algorithm> using namespace std; bool f(int i,char j){ // 數字字元和整數,視為相等 return i==int(j)-48; } int main() { int a[5] = {1,2,3,4,5}; char b[5] = {'1','2','3','4','5'}; // 呼叫自定義的比較規則 bool result = equal(a,a+5,b,f); cout<<result<<endl; } // 輸出結果為1
5. 翻轉reverse
reverse用於反轉容器中指定範圍內的元素,和sort函式一樣,reverse都是原地修改,其基本語法為:
reverse(container.begin(), container.end());
#include <iostream> #include <algorithm> using namespace std; int main() { int a[5] = {1,2,3,4,5}; // 也可以指定需要反轉的範圍 reverse(a,a+5); for(int i:a){ cout<<i<<' '; } } // 輸出結果為5 4 3 2 1