C++算法庫
文章目錄
- C++算法庫
- 復制操作
- copy , copy_if
- copy_n
- copy_backward
- 交換操作
- swap
- swap_ranges
- iter_swap
- 變換操作
- transform
- replace
- replace_copy replace_copy_if
算法庫提供大量用途的函數(例如查找、排序、計數、操作),它們在元素范圍上操作。
》》概念約束
》》ranges標準庫
C++20 在命名空間 std::ranges 中提供大多數算法的受約束版本,在這些算法中,范圍既可以由迭代器-哨位對,也可以由單個 range 實參指定,還支持投影和成員指針可調用對象。
std::vector<int> v {7, 1, 4, 0, -1};
std::ranges::sort(v); // 受約束算法
- 頭文件
#include <algorithm>
#include <numeric>
#include <memory>
#include <ranges> //C++20
復制操作
copy , copy_if
- copy 復制范圍
[first, last)
中的元素到從d_first
開始的另一范圍(復制目標范圍) - copy_if 對對所要求的元素則返回 ?true 的一元謂詞執行copy
first, last —要復制的元素范圍
d_first — 目標范圍的起始
vector<int> a = {1,2,3,4,5};
vector<int> b(10);
std::copy(a.begin() , a.end() , b.begin());
for(auto x : b)std::cout << x << " "; //1 2 3 4 5 0 0 0 0 0
//std::back_inserter用于動態獲取b.end()位置插入
std::copy_if(a.begin() , a.end() , std::back_inserter(b), [](int x){return x % 2 == 0;});
for(auto x : b)std::cout << x << " ";//1 2 3 4 5 0 0 0 0 0 2 4
- ranges
std::ranges::copy(a , b.begin());
std::ranges::copy_if(a , b.begin(), [](int x){return x % 2 == 0;});
copy_n
復制始于 first
的范圍中恰好 count
個值到始于 result
的范圍。
first — 復制來源的元素范圍起始
count — 要復制的元素數
result — 目標范圍起始
std::string in {"1234567890"};
std::string out;
std::copy_n(in.begin(), 4, std::back_inserter(out));//1234
std::cout << out << '\n';
- ranges
std::ranges::copy_n(in.begin(), 4, std::back_inserter(out));//1234
copy_backward
(按從后往前的順序復制一個范圍內的元素)
將范圍 [first, last)
內的元素復制到終于 d_last
的范圍。以逆序復制元素(首先復制末元素),但保持相對順序。
first, last — 要復制的元素范圍
d_last — 目標范圍的結尾
std::vector<int> source = {1,2,3,4,5};
std::vector<int> destination(6);
std::copy_backward(source.begin(), source.end(), destination.end());
for(auto x : destination)std::cout << x << " ";//0 1 2 3 4 5
- ranges
std::ranges::copy_backward(source, destination.end());
交換操作
swap
交換兩個對象的值
vector<int> a = {1,2,3,4,5};
vector<int> b = {5,4,3,2,1};
std::swap(a, b);
for(auto x : a)cout << x << " ";//5 4 3 2 1
for(auto x : b)cout << x << " ";//1 2 3 4 5
swap_ranges
交換兩個范圍的元素
在范圍 [first1, last1)
和始于 first2
的另一范圍間交換元素。
first1, last1 — 要交換的第一個元素范圍
first2 — 要交換的第二個元素范圍的起始
std::vector<char> v{'a', 'b', 'c', 'd', 'e'};
std::list<char> l{'1', '2', '3', '4', '5'};
std::swap_ranges(v.begin(), v.begin() + 3, l.begin());
for(auto x : l)cout << x << " "; //a b c 4 5
- ranges
在第一范圍 [first1, first1 + M)
與第二范圍 [first2, first2 + M)
交換
std::vector<char> v{'a', 'b', 'c', 'd', 'e' , 'f' ,'g' , 'h'};
std::ranges::swap_ranges(v.begin(), v.begin() + 2, v.begin() + 4 , v.begin() + 6);
for(auto x : v)cout << x << " "; //e f c d a b g h
iter_swap
交換兩個迭代器所指向的元素
vector<int> a = {1,2,3,4,5};
vector<int> b = {5,4,3,2,1};
std::iter_swap(a.begin() , b.begin());
std::cout << a[0] << " " << b[0] << std::endl;//5 1
變換操作
transform
將一個函數應用于某一范圍的各個元素,并在目標范圍存儲結果
應用一元函數 unary_op
到 [first1, last1)
所定義的范圍
應用二元函數 binary_op
到來自兩個范圍的元素對:一個以 [first1, last1)
定義,而另一個始于 first2
std::string s{"hello"};
std::transform(s.begin(), s.end(),s.begin(), // 寫入相同位置[](unsigned char c) { return std::toupper(c); });
std::cout << s << '\n'; //HELLOvector<int> ordinals = {1,2,3,4,5};
std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),ordinals.begin(), [](int a , int b){return a + b;});
for(auto x : ordinals)cout << x << " ";//2 4 6 8 10
- ranges
std::ranges::transform(s,s.begin(), // 寫入相同位置[](unsigned char c) { return std::toupper(c); });std::ranges::transform(ordinals , ordinals, ordinals.begin(), [](int a , int b){return a + b;});
replace
將所有滿足特定判別標準的值替換為另一個值
以 new_value
替換范圍 [first, last)
中所有滿足特定判別標準的元素。
vector<int> a = {1,2,3,2,5};
//所有為2的值替換為88
std::replace(a.begin(), a.end(), 2, 88);
for(auto x : a)cout << x << " ";// 1 88 3 88 5
- ranges
std::ranges::replace(a, 2, 88);
replace_copy replace_copy_if
復制一個范圍,并將滿足特定判別標準的元素替換為另一個值
復制來自范圍 [first, last)
的元素到始于 d_first
的范圍,復制過程中以 new_value
替換所有滿足特定判別標準的元素。
std::vector<int> v{1,1,1,2,3,4};
std::replace_copy(v.begin(), v.end(),v.begin(),1, 99);
for(auto x : v)cout << x << " ";//99 99 99 2 3 4
std::vector<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
std::replace_copy_if(v.begin(), v.end(),v.begin(),//輸出到原地開頭[](int n){ return n > 5; }, 99);
for(auto x : v)cout << x << " ";
- ranges
std::ranges::replace_copy(v,v.begin(),1, 99);
std::ranges::replace_copy_if(v,v.begin(),[](int n){ return n > 5; }, 99);