熱門文章

2023年8月24日 星期四

C++ algorithm 函式庫

作者:王一哲
日期:2023年8月24日



前言


C++ algorithm 函式庫中有許多好用的工具,例如排序用的 sort、反轉資料用的 reverse,在 APCS 及 能力競賽中都能使用 algorithm 函式庫,善用這些工具可以少寫很多程式碼。接下來的的程式碼中都省略了以下幾行
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;


不會改變容器中元素的函式


all_of 測試範圍中是否所有的元素皆符合條件


語法為
all_of(起點位址, 終點位址, 條件);
測試範圍包含起點位址,不包含終點位址,如果範圍中所有的元素皆符合條件或是範圍中沒有任何元素回傳 1,如果有任何一個元素不符合條件回傳 0。例如以下的程式碼
bool isPositive (int n) {
    return n > 0;
}

int main() {
    vector<int> a = {1, 3, 5, -2, -4, -6};
    cout << all_of(a.begin(), a.end(), isPositive) << endl;  // 印出 0
    cout << all_of(a.begin(), a.end(), [](int x){return x > 0;}) << endl;  // 印出 0
    vector<int> b = {1, 3, 5, 2, 4, 6};
    cout << all_of(b.begin(), b.end(), [](int x){return x > 0;}) << endl;  // 印出 1
    vector<int> c;
    cout << all_of(c.begin(), c.end(), [](int x){return x > 0;}) << endl;  // 印出 1
    return 0;
}


any_of 測試範圍中是否有任何一個元素符合條件


語法為
any_of(起點位址, 終點位址, 條件);
測試範圍包含起點位址,不包含終點位址,如果範圍中任何一個元素符合條件回傳 1,如果所有元素皆不符合條件或是範圍中沒有任何元素回傳 0。例如以下的程式碼
bool isPositive (int n) {
    return n > 0;
}

int main() {
    vector<int> a = {1, 3, 5, -2, -4, -6};
    cout << any_of(a.begin(), a.end(), isPositive) << endl;  // 印出 1
    cout << any_of(a.begin(), a.end(), [](int x){return x > 0;}) << endl;  // 印出 1
    vector<int> b = {-1, -3, -5, -2, -4, -6};
    cout << any_of(b.begin(), b.end(), [](int x){return x > 0;}) << endl;  // 印出 0
    vector<int> c;
    cout << any_of(c.begin(), c.end(), [](int x){return x > 0;}) << endl;  // 印出 0
    return 0;
}


none_of 測試範圍中是否沒有任何一個元素符合條件


語法為
none_of(起點位址, 終點位址, 條件);
測試範圍包含起點位址,不包含終點位址,如果範圍中沒有任何一個元素符合條件或是範圍中沒有任何元素回傳 1,如果所有元素皆符合條件回傳 0。例如以下的程式碼
bool isPositive (int n) {
    return n > 0;
}

int main() {
    vector<int> a = {1, 3, 5, -2, -4, -6};
    cout << none_of(a.begin(), a.end(), isPositive) << endl;  // 印出 0
    cout << none_of(a.begin(), a.end(), [](int x){return x > 0;}) << endl;  // 印出 0
    vector<int> b = {-1, -3, -5, -2, -4, -6};
    cout << none_of(b.begin(), b.end(), [](int x){return x > 0;}) << endl;  // 印出 1
    vector<int> c;
    cout << none_of(c.begin(), c.end(), [](int x){return x > 0;}) << endl;  // 印出 1
    return 0;
}


for_each 套用自訂函式到範圍中的所有元素


語法為
for_each(起點位址, 終點位址, 自訂函式);
範圍包含起點位址,不包含終點位址。例如以下的程式碼,編譯後執行會印出 1 3 5 2 4 6。
void myfunc (int n) {
    cout << n << " ";
}

int main() {
    vector<int> a = {1, 3, 5, 2, 4, 6};
    for_each(a.begin(), a.end(), myfunc);
    cout << endl;
    for_each(a.begin(), a.end(), [](int x){cout << x << " ";});
    cout << endl;
    return 0;
}


find 於範圍中尋找指定的元素


語法為
find(起點位址, 終點位址, 指定的元素);
範圍包含起點位址,不包含終點位址。如果有找到指定的元素,會回傳對應的迭代器,如果範圍中有好幾個指定的元素,只會回傳第一個;如果沒有找到指定的元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 2, 1, 2, 1, 2};
auto it = find(a.begin(), a.end(), 2);
cout << it - a.begin() << endl;  // it - a.begin() 才會是索引值,印出 1
if (find(a.begin(), a.end(), -1) == a.end())
    cout << "-1 is not in a." << endl;  // -1 不在 a 之中


find_if 於範圍中尋找符合條件的元素


語法為
find_if(起點位址, 終點位址, 條件);
範圍包含起點位址,不包含終點位址。如果有找到符合條件的元素,會回傳對應的迭代器,如果範圍中有好幾個符合條件的元素,只會回傳第一個;如果沒有找到符合條件的元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
bool isEven (int n) {
    return n%2 == 0;
}

int main() {
    vector<int> a = {1, 3, 5, 2, 4, 6};
    auto it = find_if(a.begin(), a.end(), isEven);
    cout << it - a.begin() << endl;  // it - a.begin() 才會是索引值,印出 3
    auto it2 = find_if(a.begin(), a.end(), [](int x){return x%2 == 0;});
    cout << it2 - a.begin() << endl;  // it2 - a.begin() 才會是索引值,印出 3
    vector<int> b = {1, 3, 5, 7, 9, 11};
    auto it3 = find_if(b.begin(), b.end(), isEven);
    cout << it3 - b.begin() << endl;  // it3 - b.begin() 才會是索引值,印出 6,b 當中所有的元素都是奇數
    auto it4 = find_if(b.begin(), b.end(), [](int x){return x%2 == 0;});
    cout << it4 - b.begin() << endl;  // it4 - b.begin() 才會是索引值,印出 6,b 當中所有的元素都是奇數
    return 0;
}


find_if_not 於範圍中尋找不符合條件的元素


語法為
find_if_not(起點位址, 終點位址, 條件);
範圍包含起點位址,不包含終點位址。如果有找到不符合條件的元素,會回傳對應的迭代器,如果範圍中有好幾個不符合條件的元素,只會回傳第一個;如果沒有找到不符合條件的元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
bool isEven (int n) {
    return n%2 == 0;
}

int main() {
    vector<int> a = {1, 3, 5, 2, 4, 6};
    auto it = find_if_not(a.begin(), a.end(), isEven);
    cout << it - a.begin() << endl;  // it - a.begin() 才會是索引值,印出 0
    auto it2 = find_if_not(a.begin(), a.end(), [](int x){return x%2 == 0;});
    cout << it2 - a.begin() << endl;  // it2 - a.begin() 才會是索引值,印出 0
    vector<int> b = {2, 4, 6, 8, 10, 12};
    auto it3 = find_if_not(b.begin(), b.end(), isEven);
    cout << it3 - b.begin() << endl;  // it3 - b.begin() 才會是索引值,印出 6,b 當中所有的元素都是偶數
    auto it4 = find_if_not(b.begin(), b.end(), [](int x){return x%2 == 0;});
    cout << it4 - b.begin() << endl;  // it4 - b.begin() 才會是索引值,印出 6,b 當中所有的元素都是偶數
    return 0;
}


find_end 於範圍中尋找最後一個子序列 (subsequence)


語法為
find_end(起點位址, 終點位址, 子序列起點位址, 子序列終點位址);
範圍包含起點位址,不包含終點位址。如果有找到子序列,會回傳對應的迭代器,如果範圍中有好幾個子序列,只會回傳最後一個;如果沒有找到子序列,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6, 1, 3, 5, 2, 4, 6}, b = {5, 2, 4}, c = {-1, -2, -3};
auto it = find_end(a.begin(), a.end(), b.begin(), b.end());
cout << it - a.begin() << endl;  // it - a.begin() 才會是索引值,印出 8
auto it2 = find_end(a.begin(), a.end(), c.begin(), c.end());
cout << it2 - a.begin() << endl;  // it2 - a.begin() 才會是索引值,印出 12


find_first_of 於範圍1中尋找第一個出現的範圍2中任何一個元素


語法為
find_first_of(起點位址, 終點位址, 起點位址1, 終點位址2);
範圍包含起點位址,不包含終點位址。如果有找到範圍2中任何一個元素,會回傳對應的迭代器,如果範圍1中有好幾個範圍2中任何一個元素,只會回傳第一個;如果沒有找到範圍2中任何一個元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6, 1, 3, 5, 2, 4, 6}, b = {2, 5, 4}, c = {-1, -2, -3};
auto it = find_first_of(a.begin(), a.end(), b.begin(), b.end());
cout << it - a.begin() << endl;  // it - a.begin() 才會是索引值,印出 2
auto it2 = find_first_of(a.begin(), a.end(), c.begin(), c.end());
cout << it2 - a.begin() << endl;  // it2 - a.begin() 才會是索引值,印出 12


adjancet_find 於範圍中尋找兩個相鄰且相同的元素


語法為
adjancet_find(起點位址, 終點位址);
範圍包含起點位址,不包含終點位址。如果有找到兩個相鄰且相同的元素,會回傳第一個元素對應的迭代器,如果範圍中有好幾組兩個相鄰且相同的元素,只會回傳第一組;如果沒有找到兩個相鄰且相同的元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 2, 1, 3, 5, 3, 3, 4, 6};
auto it = adjacent_find(a.begin(), a.end());
cout << "a[" << it - a.begin() << "] = " << *it << endl;    // 印出 a[3] = 2
auto it2 = adjacent_find(++it, a.end());
cout << "a[" << it2 - a.begin() << "] = " << *it2 << endl;  // 印出 a[8] = 3
vector<int> b = {1, 3, 5, 2, 4, 6};
auto it3 = adjacent_find(b.begin(), b.end());
cout << it3 - b.begin() << endl;    // 印出 6


count 於範圍中計算指定元素的個數


語法為
count(起點位址, 終點位址, 指定的元素);
範圍包含起點位址,不包含終點位址,回傳值格式為 int。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6, 1, 1, 2, 2, 2, 3};
cout << count(a.begin(), a.end(), 1) << endl;   // 印出 3
cout << count(a.begin(), a.end(), -1) << endl;  // 印出 0


count_if 於範圍中計算符合條件的元素個數


語法為
count_if(起點位址, 終點位址, 條件);
範圍包含起點位址,不包含終點位址,回傳值格式為 int。例如以下的程式碼。
bool isEven (int n) {
    return n%2 == 0;
}

int main() {
    vector<int> a = {1, 3, 5, 2, 4, 6, 8};
    cout << count_if(a.begin(), a.end(), isEven) << endl;   // 印出 4
    cout << count_if(a.begin(), a.end(), [](int x){return x%2 == 0;}) << endl;  // 印出 4
    cout << count_if(a.begin(), a.end(), [](int x){return x < 0;}) << endl;  // 印出 0
    return 0;
}


mismatch 於兩組範圍中尋找第一組不相同的元素


語法為
mismatch(起點位址, 終點位址, 起點位址2, 終點位址2);
範圍包含起點位址,不包含終點位址,回傳值格式為兩個迭代器的 pair。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6}, b = {1, 2, 5, 2, 3, 6};
auto it = mismatch(a.begin(), a.end(), b.begin(), b.end());
cout << "The first mismatching elements are " << *it.first << " and " << *it.second << endl;  // 印出 The first mismatching elements are 3 and 2
it = mismatch(++(it.first), a.end(), ++(it.second), b.end());
cout << "The second mismatching elements are " << *it.first << " and " << *it.second << endl;  // 印出 The first mismatching elements are 4 and 3


equal 檢查兩組範圍中的元素內容及順序是否相等


語法為
equal(起點位址, 終點位址, 起點位址2, 終點位址2);
範圍包含起點位址,不包含終點位址,回傳值格式為 1 或 0。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6}, b = {2, 4, 6};
cout << equal(a.begin(), a.end(), b.begin(), b.end()) << endl;    // 印出 0
cout << equal(a.begin()+3, a.end(), b.begin(), b.end()) << endl;  // 印出 1


is_permutation 檢查兩組範圍中的元素內容是否相等


語法為
is_permutation(起點位址, 終點位址, 起點位址2, 終點位址2);
範圍包含起點位址,不包含終點位址,回傳值格式為 1 或 0。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6}, b = {2, 6, 4};
cout << is_permutation(a.begin(), a.end(), b.begin(), b.end()) << endl;    // 印出 0
cout << is_permutation(a.begin()+3, a.end(), b.begin(), b.end()) << endl;  // 印出 1


search 於範圍中尋找第一個子序列 (subsequence)


語法為
search(起點位址, 終點位址, 子序列起點位址, 子序列終點位址);
範圍包含起點位址,不包含終點位址。如果有找到子序列,會回傳對應的迭代器,如果範圍中有好幾個子序列,只會回傳第一個;如果沒有找到子序列,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6, 1, 3, 5}, b = {3, 5}, c = {2, 6};
auto it = search(a.begin(), a.end(), b.begin(), b.end());
if (it != a.end()) {
    cout << "{3, 5} is found in a[" << it - a.begin() << "]" << endl;   // 印出 1
} else {
    cout << "{3, 5} is not found in a." << endl;
}
auto it2 = search(a.begin(), a.end(), c.begin(), c.end());
if (it2 != a.end()) {
    cout << "{2, 6} is found in a[" << it2 - a.begin() << "]" << endl;
} else {
    cout << "{2, 6} is not found in a." << endl;   // 印出 {2, 6} is not found in a.
}


search_n 於範圍中尋找連續且指定數量的特定元素


語法為
search_n(起點位址, 終點位址, 數量, 特定元素);
範圍包含起點位址,不包含終點位址。如果有找到連續且指定數量的特定元素,會回傳第一個元素對應的迭代器;如果沒有找到連續且指定數量的特定元素,會回傳終點位址對應的迭代器。例如以下的程式碼。
vector<int> a = {1, 3, 3, 5, 5, 5, 7, 7, 7, 7};
auto it = search_n(a.begin(), a.end(), 2, 3);
if (it != a.end()) {
    cout << "Two 3s are found in a[" << it - a.begin() << "]" << endl;   // 印出 1
} else {
    cout << "Two 3s are not found in a." << endl;
}
auto it2 = search_n(a.begin(), a.end(), 4, 5);
if (it2 != a.end()) {
    cout << "Four 5s are found in a[" << it2 - a.begin() << "]" << endl;
} else {
    cout << "Four 5s are not found in a." << endl;   // 印出 Four 5s are not found in a.
}
vector<int> b = {1, 3, 5, 7, 3, 5, 7, 5, 7, 7};
auto it3 = search_n(b.begin(), b.end(), 2, 3);
cout << it3 - b.begin() << endl;   // 印出 10


會改變容器中元素的函式


copy 複製指定範圍中的元素


語法為
copy(起點位址, 終點位址, 存放資料起點位址);
範圍包含起點位址,不包含終點位址。例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
copy(a.begin()+2, a.end()-1, b.begin());    // b 的長度為 6,只複製了 3 個元素
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 3 4 5 0 0 0
vector<int> c (a.begin()+2, a.end()-1);     // 也可以在建立 vector 時複製資料
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 3 4 5


copy_n 複製指定起點位址及數量的元素


語法為
copy_n(起點位址, 數量, 存放資料起點位址);
範圍包含起點位址,不包含終點位址,存放資料的容器長度要大於、等於複製資料的數量。例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6), c (6);
copy_n(a.begin()+2, 3, b.begin());
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 3 4 5 0 0 0
copy_n(a.begin(), 6, c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 2 3 4 5 6


copy_if 複製範圍中符合條件的元素


語法為
copy_if(起點位址, 終點位址, 存放資料起點位址, 條件);
範圍包含起點位址,不包含終點位址,存放資料的容器長度要大於、等於複製資料的數量。例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6), c (6);
copy_if(a.begin(), a.end(), b.begin(), [](int x){return x%2 == 0;});
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 2 4 6 0 0 0
copy_if(a.begin(), a.end(), c.begin(), [](int x){return x%2 == 1;});
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 3 5 0 0 0


copy_backward 複製指定範圍中的元素並從存放資料終點位址向前填入


語法為
copy_backward(起點位址, 終點位址, 存放資料終點位址);
範圍包含起點位址,不包含終點位址,存放資料的容器長度要大於、等於複製資料的數量,填入的資料仍然按照原來的順序。例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (8);
copy_backward(a.begin(), a.end(), b.end());
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 0 0 1 2 3 4 5 6


move 移動指定範圍中的元素至存放資料起點位址


語法為
move(起點位址, 終點位址, 存放資料起點位址);
存放資料容器名稱 = move(來源資料容器名稱);
範圍包含起點位址,不包含終點位址,存放資料的容器長度要大於、等於複製資料的數量。例如以下的程式碼,在說明書中像是第2行程式碼會清空 a 的內容,但是我測試時 a 仍然保有原來的內容。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
move(a.begin(), a.end(), b.begin());
cout << "a" << endl;
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
cout << "b" << endl;
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 2 3 4 5 6
b = move(a);
cout << "a" << endl;
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 沒有印出任何內容
cout << "b" << endl;
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 2 3 4 5 6


move_backward 移動指定範圍中的元素並從存放資料終點位址向前填入


語法為
move_backward(起點位址, 終點位址, 存放資料終點位址);
範圍包含起點位址,不包含終點位址,存放資料的容器長度要大於、等於複製資料的數量,填入的資料仍然按照原來的順序。例如以下的程式碼,在說明書中像是第2行程式碼會清除 a[1]、a[2]、a[3],但是我測試時 a 仍然保有原來的內容。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
move_backward(a.begin()+1, a.begin()+4, b.end());
cout << "a" << endl;
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
cout << "b" << endl;
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 0 0 0 2 3 4


swap 交換兩個容器的資料


語法為
swap(容器1, 容器2);
例如以下的程式碼。
int a = 1, b = -1;
swap(a, b);
cout << "a = " << a << ", b = " << b << endl;  // 印出 a = -1, b = 1
vector<int> c = {1, 2, 3}, d = {4, 5, 6};
swap(c, d);
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 4 5 6
for(auto it = d.begin(); it != d.end(); it++)
    cout << *it << " \n"[it == d.end()-1];  // 印出 1 2 3


swap_ranges 交換兩個容器中指定範圍的元素


語法為
swap_ranges(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b = {6, 5, 4, 3, 2, 1};
swap_ranges(a.begin()+1, a.begin()+4, b.begin());
cout << "a" << endl;
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 6 5 4 5 6
cout << "b" << endl;
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 2 3 4 3 2 1


iter_swap 交換兩個迭代器對應的元素


語法為
iter_swap(迭代器1, 迭代器2);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b = {6, 5, 4, 3, 2, 1};
iter_swap(a.begin()+1, b.begin()+2);
cout << "a" << endl;
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 4 3 4 5 6
cout << "b" << endl;
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 6 5 2 3 2 1


transform 套用函式到容器1的元素,將結果儲存到目標位址


語法為
transform(容器1起點位址, 容器1終點位址, 目標起點位址, 函式);
transform(容器1起點位址, 容器1終點位址, 容器2起點位址, 目標起點位址, 函式);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
transform(a.begin(), a.end(), b.begin(), [](int x){return ++x;});
cout << "Plus one" << endl;
cout << "a: ";
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 a: 1 2 3 4 5 6
cout << "b: ";
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 b: 2 3 4 5 6 7
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<int>());
cout << "Plus b to a" << endl;
cout << "a: ";
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 a: 3 5 7 9 11 13
cout << "b: ";
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 b: 2 3 4 5 6 7


replace 取代範圍中指定的元素


語法為
replace(起點位址, 終點位址, 被取代的元素, 新的元素);
例如以下的程式碼。
vector<int> a = {1, 3, 2, 4, 3, 6};
replace(a.begin(), a.end(), 3, -3);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 a: 1 -3 2 4 -3 6


replace_if 取代範圍中符合條件的元素


語法為
replace_if(起點位址, 終點位址, 條件, 新的元素);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
replace_if(a.begin(), a.end(), [](int x){return x%2 == 0;}, 0);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 0 3 0 5 0


replace_copy 取代容器1中符合條件的元素並儲存到容器2


語法為
replace_copy(容器1起點位址, 容器1終點位址, 容器2起點位址, 被取代的元素, 新的元素);
例如以下的程式碼。
vector<int> a = {1, 3, 2, 4, 3, 6}, b (6);
replace_copy(a.begin(), a.end(), b.begin(), 3, -3);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 3 2 4 3 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 -3 2 4 -3 6


replace_copy_if 複製容器1的元素,取代其中符合條件的元素,再儲存到容器2


語法為
replace_copy_if(容器1起點位址, 容器1終點位址, 容器2起點位址, 條件, 新的元素);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
replace_copy_if(a.begin(), a.end(), b.begin(), [](int x){return x%2 == 0;}, 0);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 0 3 0 5 0


fill 於指定範圍內填入元素


語法為
fill(起點位址, 終點位址, 填入的元素);
例如以下的程式碼。
vector<int> a (6);
fill(a.begin()+1, a.begin()+4, -1);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 0 -1 -1 -1 0 0


fill_n 於指定起點開始填入指定數量的元素


語法為
fill_n(起點位址, 數量, 填入的元素);
例如以下的程式碼。
vector<int> a (6);
fill_n(a.begin()+1, 3, -1);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 0 -1 -1 -1 0 0


generate 於指定範圍填入代入自訂函式産生的元素


語法為
generate(起點位址, 終點位址, 自訂函式);
例如以下的程式碼。
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;

int main() {
    srand(time(NULL));
    vector<int> a (6);
    generate(a.begin(), a.end(), [](){return rand()%10;});
    for(auto it = a.begin(); it != a.end(); it++)
        cout << *it << " \n"[it == a.end()-1];  // 隨機印出 6 個 0 ~ 9 的整數
    return 0;
}


generate_n 於指定起點位址開始填入指定數量、代入自訂函式産生的元素


語法為
generate_n(起點位址, 數量, 自訂函式);
例如以下的程式碼。
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;

int main() {
    srand(time(NULL));
    vector<int> a (6);
    generate_n(a.begin(), 6, [](){return rand()%10;});
    for(auto it = a.begin(); it != a.end(); it++)
        cout << *it << " \n"[it == a.end()-1];  // 隨機印出 6 個 0 ~ 9 的整數
    return 0;
}


remove 移除範圍中指定的元素


語法為
remove(起點位址, 終點位址, 要移除的元素);
回傳值為範圍中沒有被移除的元素終點位址,例如以下的程式碼。
vector<int> a = {1, 3, 2, 4, 3, 6};
auto itEnd = remove(a.begin(), a.end(), 3);
for(auto it = a.begin(); it != itEnd; it++)
    cout << *it << " \n"[it == itEnd-1];  // 印出 1 2 4 6


remove_if 移除範圍中符合條件的元素


語法為
remove_if(起點位址, 終點位址, 條件);
回傳值為範圍中沒有被移除的元素終點位址,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
auto itEnd = remove_if(a.begin(), a.end(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != itEnd; it++)
    cout << *it << " \n"[it == itEnd-1];  // 印出 1 3 5


remove_copy 移除容器1中指定元素後將剩下的元素填入容器2


語法為
remove_copy(容器1起點位址, 容器1終點位址, 容器2起點位址, 要移除的元素);
例如以下的程式碼。
vector<int> a = {1, 3, 2, 4, 3, 6}, b (6);
remove_copy(a.begin(), a.end(), b.begin(), 3);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 3 2 4 3 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 2 4 6 0 0


remove_copy_if 移除容器1中符合條件的元素後將剩下的元素填入容器2


語法為
remove_copy_if(容器1起點位址, 容器1終點位址, 容器2起點位址, 條件);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
remove_copy_if(a.begin(), a.end(), b.begin(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 3 5 0 0 0


remove_copy_if 移除容器1中符合條件的元素後將剩下的元素填入容器2


語法為
remove_copy_if(容器1起點位址, 容器1終點位址, 容器2起點位址, 條件);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
remove_copy_if(a.begin(), a.end(), b.begin(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 3 5 0 0 0


unique 如果範圍中有連續出現的元素,只留下第一個


語法為
unique(起點位址, 終點位址);
回傳值為留下的資料終點位址,例如以下的程式碼。
vector<int> a = {1, 2, 2, 3, 3, 2};
auto itEnd = unique(a.begin(), a.end());
a.resize(itEnd - a.begin());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 2


unique_copy 如果範圍中有連續出現的元素,只留下第一個,將留下的元素複製到另一個容器


語法為
unique_copy(容器1起點位址, 容器1終點位址, 容器2起點位址);
回傳值為容器2填入資料的終點位址,例如以下的程式碼。
vector<int> a = {1, 2, 2, 3, 3, 2}, b (6);
auto itEnd = unique_copy(a.begin(), a.end(), b.begin());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 2 3 3 2
b.resize(itEnd - b.begin());
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 2 3 2


reverse 將範圍中的元素前後反轉


語法為
reverse(起點位址, 終點位址);
沒有回傳值,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
reverse(a.begin(), a.end());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 6 5 4 3 2 1


reverse_copy 將範圍中的元素前後反轉再複製到容器2


語法為
reverse_copy(容器1起點位址, 容器1終點位址, 容器2起點位址);
不會改變容器1的內容。例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
reverse_copy(a.begin(), a.end(), b.begin());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 6 5 4 3 2 1


rotate 將範圍中的元素向前平移,最前面的元素移到最後面


語法為
rotate(起點位址, 新的起點位址, 終點位址);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
rotate(a.begin(), a.begin()+3, a.end());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 4 5 6 1 2 3


rotate_copy 將範圍中的元素向前平移,最前面的元素移到最後面,再複製到容器2


語法為
rotate_copy(起點位址, 新的起點位址, 終點位址, 容器2起點位址);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (6);
rotate_copy(a.begin(), a.begin()+3, a.end(), b.begin());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 4 5 6 1 2 3


random_shuffle 隨機排列範圍中的元素


語法為
random_shuffle(起點位址, 終點位址);
可以使用內建的 rand 函式,並搭配 srant(time(NULL)),例如以下的程式碼。
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;

int main() {
    srand(time(NULL));
    vector<int> a = {1, 2, 3, 4, 5, 6};
    random_shuffle(a.begin(), a.end());
    for(auto it = a.begin(); it != a.end(); it++)
        cout << *it << " \n"[it == a.end()-1];  // 1 ~ 6 隨機排列
    return 0;
}


shuffle 隨機排列範圍中的元素


語法為
shuffle(起點位址, 終點位址, default_random_engine(seed));
使用 random 函式庫的 default_random_engine 函式,並搭配 chrono 函式庫的工具産生亂數種子,例如以下的程式碼。
#include <iostream>
#include <algorithm>
#include <vector>
#include <random>
#include <chrono>
using namespace std;

int main() {
    unsigned int seed = chrono::system_clock::now().time_since_epoch().count();
    vector<int> a = {1, 2, 3, 4, 5, 6};
    shuffle(a.begin(), a.end(), default_random_engine(seed));
    for(auto it = a.begin(); it != a.end(); it++)
        cout << *it << " \n"[it == a.end()-1];  // 1 ~ 6 隨機排列
    return 0;
}


操作分區


is_partitioned 檢查範圍中所有元素是否符合條件


語法為
is_partitioned(起點位址, 終點位址, 條件);
如果所有元素都符合條件回傳 1,如果有任何一個元素不符合條件回傳0,例如以下的程式碼。
vector<int> a = {0, 2, 4, 5, 6, 8}, b = {0, 2, 4, 6, 8, 10};
cout << is_partitioned(a.begin(), a.end(), [](int x){return x%2 == 0;}) << endl;  // 印出 0
cout << is_partitioned(b.begin(), b.end(), [](int x){return x%2 == 0;}) << endl;  // 印出 1


partition 依照條件將範圍分區


語法為
partition(起點位址, 終點位址, 條件);
回傳值為分區位址對應的迭代器,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
auto bound = partition(a.begin(), a.end(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != bound; it++) cout << *it << " ";  // 印出 6 2 4
cout << endl;
for(auto it = bound; it != a.end(); it++) cout << *it << " ";    // 印出 3 5 1
cout << endl;


stable_partition 依照條件將範圍分區並排序


語法為
stable_partition(起點位址, 終點位址, 條件);
回傳值為分區位址對應的迭代器,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
auto bound = stable_partition(a.begin(), a.end(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != bound; it++) cout << *it << " ";  // 印出 2 4 6
cout << endl;
for(auto it = bound; it != a.end(); it++) cout << *it << " ";    // 印出 1 3 5
cout << endl;


partition_copy 依照條件將範圍分區並存入另外兩個容器


語法為
partition_copy(起點位址, 終點位址, 容器2起點位址, 容器3起點位址, 條件);
例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b (3), c(3);
partition_copy(a.begin(), a.end(), b.begin(), c.begin(), [](int x){return x%2 == 0;});
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 2 4 6
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 3 5


partition_point 回傳依照條件將範圍分區的位址


語法為
partition_point(起點位址, 終點位址, 條件);
回傳值為分區位址對應的迭代器,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b;
partition(a.begin(), a.end(), [](int x){return x%2 == 0;});
auto bound = partition_point(a.begin(), a.end(), [](int x){return x%2 == 0;});
b.assign(a.begin(), bound);
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 6 2 4 3 5 1
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 6 2 4


排序


sort 排序範圍內的元素


語法為
sort(起點位址, 終點位址, 比較式);
比較式預設值為由小到大排序,也可以引用內建函式 greater 由大到小排序,或是依照自訂函式排序,例如以下的程式碼。
vector<int> a = {1, 3, 5, 2, 4, 6};
sort(a.begin(), a.end());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 6
sort(a.begin(), a.end(), greater<>());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 6 5 4 3 2 1


stable_sort 排序範圍內的元素,如果元素相等時保持原來的順序


語法為
stable_sort(起點位址, 終點位址, 比較式);
例如以下的程式碼。
vector<float> a = {2.5, 2.1, 2.3, 1.5, 1.1, 1.3};
stable_sort(a.begin(), a.end(), [](float x, float y){return int(x) < int(y);});
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1.5 1.1 1.3 2.5 2.1 2.3


partial_sort 排序範圍內部分的元素


語法為
partial_sort(起點位址, 中點位址, 終點位址, 比較式);
比較式預設值為由小到大排序,如果採用預設值,中點位址前會放入整個範圍中由小到大排序的元素,再由中點位址開始放入剩下的元素,如以下的程式碼。
vector<int> a = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
partial_sort(a.begin(), a.begin()+5, a.end());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 2 3 4 5 9 7 6 8 10


partial_sort_copy 排序容器1中指定範圍的元素並複製到容器2


語法為
partial_sort_copy(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 比較式);
比較式預設值為由小到大排序,不會改變容器1的內容,例如以下的程式碼。
vector<int> a = {1, 10, 2, 9, 3, 8, 4, 7, 5, 6}, b(5);
partial_sort_copy(a.begin(), a.begin()+5, b.begin(), b.end());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 10 2 9 3 8 4 7 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 1 2 3 9 10 
partial_sort_copy(a.begin(), a.begin()+5, b.begin(), b.end(), greater<>());
for(auto it = a.begin(); it != a.end(); it++)
    cout << *it << " \n"[it == a.end()-1];  // 印出 1 10 2 9 3 8 4 7 5 6
for(auto it = b.begin(); it != b.end(); it++)
    cout << *it << " \n"[it == b.end()-1];  // 印出 10 9 3 2 1 


is_sorted 檢查範圍中的元素是否已排序


語法為
is_sorted(起點位址, 終點位址, 比較式);
比較式預設值為由小到大排序,如果已排序回傳 1,如果未排序回傳 0,例如以下的程式碼。
vector<int> a = {1, 3, 5, 6, 4, 2};
cout << is_sorted(a.begin(), a.end()) << endl;  // 印出 0
cout << is_sorted(a.begin(), a.begin()+3) << endl;  // 印出 1
cout << is_sorted(a.begin()+3, a.end(), greater<>()) << endl;  // 印出 1
sort(a.begin(), a.end());
cout << is_sorted(a.begin(), a.end()) << endl;  // 印出 1


is_sorted_until 找出範圍中第一個未由小到大排序的元素位址


語法為
is_sorted_until(起點位址, 終點位址);
如果所有元素都已經由小到大排序,回傳終點位址,例如以下的程式碼。
vector<int> a = {1, 3, 5, 6, 4, 2};
auto it = is_sorted_until(a.begin(), a.end());
cout << it - a.begin() << endl;  // 印出 4
sort(a.begin(), a.end());
auto it2 = is_sorted_until(a.begin(), a.end());
cout << it2 - a.begin() << endl;  // 印出 6


二分搜尋


這些函式只能用在已經全部或部分排序的資料。


lower_bound、upper_bound、equal_range 找出範圍中指定元素的位址


語法為
lower_bound(起點位址, 終點位址, 元素);
upper_bound(起點位址, 終點位址, 元素);
equal_range(起點位址, 終點位址, 元素);
lower_bound 回傳值為指定元素左側的位址,upper_bound 回傳值為指定元素右側的位址,equal_range 回傳值格式為 pair,同時包含 lower_bound 及 upper_bound,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
auto it = lower_bound(a.begin(), a.end(), 3);
cout << it - a.begin() << endl;   // 印出 2
auto it2 = upper_bound(a.begin(), a.end(), 3);
cout << it2 - a.begin() << endl;  // 印出 3
auto bounds = equal_range(a.begin(), a.end(), 3);
cout << "lower_bound: " << bounds.first - a.begin() << " upper_bound: " << bounds.second - a.begin() << endl;  // 印出 lower_bound: 2 upper_bound: 3


binary_search 用二分搜尋法檢查範圍中是否有指定元素


語法為
binary_search(起點位址, 終點位址, 元素);
如果找到指定元素回傳 1,如果沒有找到指定元素回傳 0,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6};
cout << binary_search(a.begin(), a.end(), 3) << endl;   // 印出 1
cout << binary_search(a.begin(), a.end(), -3) << endl;  // 印出 0


處理已排序的資料


merge 合併兩組已排序的資料並存入另一個容器


語法為
merge(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 容器3起點位址);
例如以下的程式碼。
vector<int> a = {1, 3, 5, 7, 9}, b = {2, 4, 6, 8, 10}, c (10);
merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 2 3 4 5 6 7 8 9 10


includes 檢查容器1是否包含容器2的資料且順序相同


語法為
includes(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址);
如果是回傳 1,反之回傳 0,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5, 6}, b = {2, 3, 4}, c = {4, 3, 2};
cout << includes(a.begin(), a.end(), b.begin(), b.end()) << endl;  // 印出 1
cout << includes(a.begin(), a.end(), c.begin(), c.end()) << endl;  // 印出 0


set_union 將容器1、2的元素組合成聯集存入容器3


語法為
set_union(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 容器3起點位址);
例如以下的程式碼。
vector<int> a = {1, 3, 3, 5, 5}, b = {2, 2, 4, 6, 6}, c (15);
auto itEnd = set_union(a.begin(), a.end(), b.begin(), b.end(), c.begin());
c.resize(itEnd - c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 2 2 3 3 4 5 5 6 6


set_intersection 將容器1、2的元素組合成交集存入容器3


語法為
set_intersection(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 容器3起點位址);
例如以下的程式碼。
vector<int> a = {1, 3, 3, 5, 5}, b = {1, 2, 3, 4, 5}, c (15);
auto itEnd = set_intersection(a.begin(), a.end(), b.begin(), b.end(), c.begin());
c.resize(itEnd - c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 3 5


set_difference 將容器1、2的元素組合成差集存入容器3


語法為
set_difference(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 容器3起點位址);
將容器1的元素刪除容器2中也有的元素,剩下的元素存入容器3,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5}, b = {1, 3, 3, 5, 5}, c (15);
auto itEnd = set_difference(a.begin(), a.end(), b.begin(), b.end(), c.begin());
c.resize(itEnd - c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 2 4


set_symmetric_difference 將容器1、2的元素組合成對稱差集存入容器3


語法為
set_symmetric_difference(容器1起點位址, 容器1終點位址, 容器2起點位址, 容器2終點位址, 容器3起點位址);
對稱差是將聯集扣掉交集,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5}, b = {2, 4, 6, 8, 10}, c (15);
auto itEnd = set_symmetric_difference(a.begin(), a.end(), b.begin(), b.end(), c.begin());
c.resize(itEnd - c.begin());
for(auto it = c.begin(); it != c.end(); it++)
    cout << *it << " \n"[it == c.end()-1];  // 印出 1 3 5 6 8 10


最大值、最小值


min 回傳最小值、max 回傳最大值、minmax 同時回傳最小值及最大值


語法為
min({元素1, 元素2, 元素3, ...});
max({元素1, 元素2, 元素3, ...});
minmax({元素1, 元素2, 元素3, ...});
例如以下的程式碼。
cout << "min = " << min({1, 2, 3, 4, 5}) << endl;  // 印出 min = 1
cout << "max = " << max({1, 2, 3, 4, 5}) << endl;  // 印出 max = 5
auto result = minmax({1, 2, 3, 4, 5});
cout << "min = " << result.first <<  ", max = " << result.second << endl;  // 印出 min = 1, max = 5


min_element 回傳範圍中的最小值、max_element 回傳範圍中的最大值、minmax_element 同時回傳範圍中的最小值及最大值


語法為
min_element({元素1, 元素2, 元素3, ...});
max_element({元素1, 元素2, 元素3, ...});
minmax_element({元素1, 元素2, 元素3, ...});
min_element 及 max_element 回傳值為對應的迭代器,minmax_element 回傳值為迭代器的 pari,例如以下的程式碼。
vector<int> a = {1, 2, 3, 4, 5};
auto it1 = min_element(a.begin(), a.end());
cout << "The min element of a is a[" << it1 - a.begin() << "] = " << *it1 << endl;  // 印出 The min element of a is a[0] = 1
auto it2 = max_element(a.begin(), a.end());
cout << "The max element of a is a[" << it2 - a.begin() << "] = " << *it2 << endl;  // 印出 The max element of a is a[4] = 5
auto result = minmax_element(a.begin(), a.end());
cout << "min(a) = " << *(result.first) <<  ", max(a) = " << *(result.second) << endl;  // 印出 min(a) = 1, max(a) = 5


結語


以上是 algorithm 函式庫大部分的函式,其中我最常用到的函式為 sort、reverse、find、count、min、max,尤其是 sort,在競賽及檢定中經常用到,如果不使用 sort 就要當場寫氣泡排序或是快速排序,會浪費不少時間。


參考資料


cplusplus.com algorithm


HackMD 版本連結:https://hackmd.io/@yizhewang/rk4Rokyp3

沒有留言:

張貼留言