在C++11標准中定義了很多算法,這些算法可以讓我們很方便的操作各種容器和數組,這里要注意一下,這些算法操作的並非容器,而是迭代器,然后通過迭代器來操作容器中的數據,算法本身並不會關注容器中保存的數據的類型。
以下是我對常識的算法的總結,這些算法大部分都在algorithm.h中,還有一些在numeric.h中。
這里我們的容器都用這幾個:
vector<string> vec;
vector<int> vec1;
vec<string> vec2;
1.find();
find()算法的作用是在指定的一段序列中查找某個數,包含三個參數,前兩個參數是表示元素范圍的迭代器,第三個參數是要查找的值。
例:fing(vec.begin(), vec.end(), val); //在vec中查找值val,該val可以是數字、字符串。
2.count();
count()算法的作用是查看給定序列中給定值出現的次數,同樣包含三個參數,前兩個參數是表示元素范圍的迭代器,第三個參數是要查找的值。
例:count(vec1.begin(), vec1.end(), 2);//在vec1中查看2出現的次數。
3.accumulate();//該函數在numeric.h文件中
accumulate()函數的作用是計算指定范圍中各個數相加的和。包含三個參數,前兩個參數是求和的序列范圍,第三個參數是和的初始值。
例:accumulate(vec1.begin(), vec1.end(), 0);//計算vec1中各個數相加的總和,和的初始值為0;
4.equal();
equal()算法的作用是確定兩個序列是否保存相同的值,此算法接受三個迭代器,前兩個迭代器表示第一個序列中元素的范圍,第三個迭代器表示第二個序列的手元素。如果相等,則返回true, 否則返回false;
equal(vec.begin(), vec.end(), vec2.begin());//比較vec和vec2中的元素是否相同。
5.fill();
fill()算法的作用是對一個范圍內的所有元素賦值,包含三個參數,前兩個參數接受一對迭代器表示一個范圍,第三個迭代器接受一個值。
例:fill(vec.begin(), vec.end(), "");//將vec中的所有元素都置為空。
6.fill_n();
fill_n算法的作用是將給定值賦給迭代器指向的元素開始的指定個元素。第一個參數接受一個迭代器,第二個元素接受一個計數值,第三個迭代器接受一個值。
例:fill_n(vec.begin(), vec.size(), "");//將vec中的所有元素置為空。
注:這里介紹一下back_inserter,它是一種插入迭代器,是一種向容器中添加元素的迭代器,它定義在iterator.h中,每調用一次back_inserter,函數則會調用一 次push_back。
例:auto i = back_inseter(vec1);//通過它賦值會將元素添加到vec中
*i = 42;//vec1中現有有一個元素,值為42
這里back_inserter常用來創建一個迭代器作為算法的目的位置來使用。
例:fill_n(back_inserter(vec1), 10, 0);//向vec1的末尾添加10個元素,元素值為0;
7.copy();
copy()算法將輸入范圍中的元素拷貝到目的序列中。包括三個參數,前兩個表示一個輸入范圍,第三個表示序列的起始位置。
例:int a1[] = {0,1,2,3,4,5,6,7,8,9};
int a2[sizeof(a1)/sizeof(*a1)];
//ret指向拷貝到a2的為元素之后的位置
auto ret = copy(begin(a1), end(a1), a2);//把a1的內容拷貝到a2.
8.replace();
replace()算法的作用是將給定序列中所有等會給定值的元素都改為另一個值,此算法接收四個參數,前兩個是迭代器,表示輸入序列范圍,第三個是表示要搜索的 值,第四個是要換的新值。
例:replace(vec.begin(), vec.end(), "", "test");//將vec中的空字符串改為test。
如果我們需要保證原序列的值不變,則可以使用replace_copy()算法,使原序列不變,將改變后的序列值拷貝給新容器。
例:replace_copy(vec.begin(), vec.end(),back_inserter(vec2), "", "test");//將修改后的新序列保存到vec2中,原序列值不變。
9.sort();
sort()算法的作用是重新排列輸入的序列中的元素,它是按照字典序列來重新排布序列。
例:vector<string> vec = {"the", "quick", "red", "for", "jump","over", "the", "slow", "red", "turtle"};
sort(vec.begin(), vec.end());
執行完后的結果:for jump over quick red slow the the turtle
10.unique();
unique()算法的作用是重新排列輸入的序列號,並使前面的每個單詞都只出現一次,返回指向不重復區域之后一個位置的迭代器。
如9的vec,auto end_unique = unique(vec.begin(), vec.end());
執行完后的結果:for jump over quick red slow the turtle the
這是如果我們需要得到一個不重復的序列,則只需要使用erase()即可,即
vec.erase(end_unique, vec.end());
執行完后的結果:for jump over quick red slow the turtle
注:為了講后面的算法,這里先普及一下謂詞,這里所謂的謂詞並不是語言語法上的謂詞,而是向算法傳遞的函數名。
例:bool isShort(const string &s1, const string &s2)
{ return s1.size() < s2.size(); }
前面的sort()算法也是可以接收謂詞的,如sort(vec.begin(), vec.end(), isShort);
該語句的意思是重新排列序列,但是是按照字符串的長度從小到大的順序排列。
11.partiton();
partition()算法的作用是對輸入的容器的內容進行划分,該算法返回一個迭代器,返回指向最后一個是謂詞為true的元素之后的位置。接受三個
參數,前兩個是元素的范圍迭代器,后一個是划分標准。
例:bool bigger(const string &a)
{ return a.size() > 5; }
partition(vec.begin(), vec.end(), bigger);//將vec划分開,前部分是長度大於5的字符串,后部分是長度小於等於5的字符串。
注:這樣再講一下可調用對象lambda,格式[capture list](parameter list)->reture type{function boby}
其中capture list(捕獲列表)是一個lambda所在函數中定義的局部變量的列表(通常為空),reture type、parameter list、function boby和其他的函數一 樣,分別表示返回類型、參數列表、函數體。像11中的例子可以寫成:
partition(vec.begin(), vec.end(), [](const string &a) {return a.size()>5;});//可以和上面達到一樣的效果
12.find_if();
find_if()算法的作用是在輸入序列中查找第一個滿足條件的元素,返回第一個指向滿足條件的元素的迭代器。
例:auto wc = find_if(vec.begin(), vec.end(), [sz](const string &a){return a.size>=sz;});//其中sz為在使用find_if的函數內部定義的局部變量。
上訴算法得到的是第一個指向長度不小於sz的元素的迭代器,如果沒有則返回vec.end();
13.for_each();
for_each()算法的主要作用是打印輸出序列。接收三個參數,前兩個為打印元素的范圍,后一個為一個可調用對象。
例:for_each(wc, vec.end(), [](const string &s){cout << s << " ";});
cout << endl;
上述程序的作用就是打印輸出序列中從wc到vec.end()中的元素。