C++標頭檔案<algorithm>中常用函式簡介

haruyuki發表於2024-09-01

概述

  標頭檔案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

相關文章