C++ Primer第十章!
#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
#include<algorithm> //泛型算法
#include<numeric>
#include<iterator> //back_inserter插入迭代器
#include<functional> //調(diào)用標(biāo)準(zhǔn)庫(kù)bind函數(shù)
using namespace std;
using namespace std::placeholders; //使用名字_n烟逊,bind函數(shù)時(shí)使用!
bool check_size(const string &s, string::size_type sz)//下標(biāo)是size_t茵汰,容器是size_type
{
return s.size() >= sz;
}
int main()
{
//只讀容器元素值
//泛型算法find捐下。泛型算法本身不會(huì)執(zhí)行容器的操作弧哎,他們只運(yùn)行在迭代器上梧田,執(zhí)行迭代器的操作淳蔼!
int val = 12;
vector<int> vec_find = { 1,2,3,12 };
auto result_int = find(vec_find.cbegin(), vec_find.cend(), val); //如果找到則返回指向迭代器,如果沒(méi)找到則返回第二個(gè)實(shí)參cend裁眯!
int sum = accumulate(vec_find.cbegin(), vec_find.cend(), 0); //求和算法鹉梨,第3個(gè)參數(shù)決定和的初值及類(lèi)型。
//find操作迭代器穿稳,所以find函數(shù)可以在任何容器中查找值存皂!泛型算法!
string val_find_string( "aa ab");
vector<string> string_find = {"a","aa ab","c"};
auto result_str = find(string_find.cbegin(), string_find.cend(), val_find_string);
//equal操作司草,元素必須支持==比較艰垂。如果對(duì)應(yīng)元素都相等,則返回true埋虹!
//equal(c1.cbegin(),c1.cend(),c2.cbegin()); 只接受一個(gè)迭代器表示第二個(gè)容器的算法,都假定第二個(gè)容器至少與第一個(gè)容器一樣長(zhǎng)娩怎!
//改變?nèi)萜髟刂瞪危盒退惴ㄖ荒芨淖冊(cè)刂担荒苤苯犹砑觿h除元素截亦!
//fill操作爬泥,fill(c1.begin(),c1.end(),10),將迭代器范圍內(nèi)元素重置為10.
//fill_n操作崩瓤,fill(c1.begin(),c1.size(),10), 向空容器中用fill寫(xiě)入元素是災(zāi)難行為袍啡,普通迭代器只能遍歷容器!
//插入迭代器back_inserter却桶,插入迭代器可以向容器中添加元素境输!普通迭代器只能遍歷元素,無(wú)法添加颖系!
vector<int> vec_back_iter;
auto it = back_inserter(vec_back_iter);
*it = 520; //向容器中添加元素值為520
//與fill_n算法使用
fill_n(back_inserter(vec_back_iter), 9, 10);//在每步迭代中嗅剖,fill_n向back_inserter創(chuàng)建的元素賦值!
//拷貝算法
int a1[] = { 1,2,3,4,5 };
int a2[sizeof(a1) / sizeof(*a1)];
auto ret = copy(begin(a1), end(a1),begin(a2)); //必須確保a2數(shù)組至少要包含a1數(shù)組一樣多的元素嘁扼!返回拷貝值之后的位置信粮!
replace(begin(a1), end(a1), 3, 10); //將數(shù)組a1中等于3的元素值改為10!
vector<int> vec_rep;
replace_copy(begin(a1), end(a1), back_inserter(vec_rep), 3, 10); //保留原序列趁啸,并拷貝原序列同時(shí)將3改為10!
//重排容器元素的算法
vector<string> vec_sort_unique = { "hello","world","!","hello","honey","!" };
sort(vec_sort_unique.begin(), vec_sort_unique.end()); //排序算法强缘,元素必須可以比較(<)督惰!
auto end_unique = unique(vec_sort_unique.begin(), vec_sort_unique.end()); //返回不重復(fù)值范圍末尾的迭代器!
vec_sort_unique.erase(end_unique, vec_sort_unique.end()); //調(diào)用容器erase操作旅掂,刪除重復(fù)元素姑丑!
//定制操作,為算法定義自己的操作辞友,分為一元謂詞和二元謂詞
vector<string> string_predicate = { "the","quick","red","fox","jumps","over","the","slow","red","turrie" };
cout << "The oldd string:";
for (auto &r : string_predicate)
{
cout << r << " ";
}
cout << endl;
sort(string_predicate.begin(), string_predicate.end());
cout << "The new1 string:";
for (auto &r : string_predicate)
{
cout << r << " ";
}
cout << endl;
stable_sort(string_predicate.begin(), string_predicate.end(), [](const string &a, const string &b) {return a.size() < b.size(); }); //sort和stable_sort栅哀,stable_sort穩(wěn)定排序算法,按照長(zhǎng)度排序(且保證之前的字典排序3屏)(二元謂詞留拾,lambda表達(dá)式!)
cout << "The new2 string:";
for (auto &r : string_predicate)
{
cout << r << " ";
}
cout << endl;
//lambda鲫尊,使用捕獲列表痴柔,捕獲sz值!(可以有引用捕獲和值捕獲疫向,但是應(yīng)該盡量避免捕獲指針或引用)
string::size_type sz = 4;
auto string_find_if = find_if(string_predicate.begin(), string_predicate.end(), [](string &a) {return a.size() > 4; });
//同上等價(jià)形式咳蔚,使用bind給函數(shù)綁定實(shí)參!auto string_find_bind=find_if(string_predicate.begin(), string_predicate.end(), bind(check_size,_1,sz));
//auto g=bind(f,a,b,_2,c,_1),從而g(x,y)相當(dāng)于f(a,b,y,c,x)搔驼! bind默認(rèn)為拷貝參數(shù)谈火,要想得到引用須使用ref()函數(shù),如ref(os)!
cout << *string_find_if << endl; //find_if返回第一個(gè)使謂詞結(jié)果非0的元素迭代器舌涨,如果不存在這樣的元素則返回尾后迭代器糯耍!
//lambda捕獲方式
//[] 空捕獲列表
//[names] 名字列表,如果加上&則為引用捕獲方式
//[&] 隱式捕獲列表囊嘉,采用引用捕獲方式
//[=] 隱式捕獲列表温技,采用值捕獲方式
//[&,identifier_list] [=,identifier_list]
//可變lambda,值捕獲通過(guò)聲明mutable扭粱,值引用取決于變量本身是否const
size_t vl_lambda = 13;
auto f = [=]()mutable{return ++vl_lambda; }; //值捕獲舵鳞,相當(dāng)于拷貝,如果想修改值捕獲對(duì)象琢蛤,則需要聲明mutable蜓堕!
vl_lambda = 0;
cout << vl_lambda << " " << f()<<endl;
vector<int> vec_lambda = { 1,-2,3,-4,5 };
transform(vec_lambda.begin(), vec_lambda.end(), vec_lambda.begin(), [](int i)->int {if(i < 0) return -i; else return i; }); //指定輸出類(lèi)型為int!
for (auto &r : vec_lambda)
{
cout << r << " ";
}
cout << endl;
//再探迭代器
//插入迭代器 綁定在容器上虐块,向容器插入元素
//流迭代器 綁定到輸入或輸出流上俩滥,可用來(lái)遍歷關(guān)聯(lián)的IO流
//反向迭代器 迭代器向后移動(dòng),除了forward_list之外的標(biāo)準(zhǔn)容器都有反向迭代器
//移動(dòng)迭代器 移動(dòng)元素
//插入迭代器分為back_inserter(push_back)贺奠、front_inserter(push_front)霜旧、inserter,使用形式auto it=back_inserter(vector容器),*it=42!
//流迭代器,istream_iterator為讀取輸入流挂据,ostream_iterator為向輸出流寫(xiě)數(shù)據(jù)
vector<int> vec_iterator;
istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
while (in_iter != eof) //流迭代器從cin讀取int值以清,直到遇到eof(被當(dāng)作尾后迭代器)退出循環(huán)!(當(dāng)遇到文件尾或遇到IO錯(cuò)誤崎逃,迭代器的值就與尾后迭代器相等)
{
vec_iterator.push_back(*in_iter++);
}
//等價(jià)于vector<int> vec(in_iter,eof)
vector<int> vec_out_iter = { 1,2,3,4,5 };
ostream_iterator<int> out_iter(cout, " "); //在每個(gè)輸出值后添加“ ”掷倔!
for (auto e : vec_out_iter)
{
*out_iter++ = e; //(*和++實(shí)際上不做任何事情)
}
cout << endl;
copy(vec_out_iter.begin(), vec_out_iter.end(), out_iter); //同上,輸出vector中元素个绍!
cout << endl;
//反向迭代器勒葱,除了forward_list,其余容器都支持反向迭代器巴柿,可以使用rbegin等獲取反向迭代器A菟洹(迭代器的范圍都是[b,e))
string str_line = "FIRST,MIDDLE,LAST";
auto rcomma = find(str_line.crbegin(), str_line.crend(), ','); //find查找對(duì)象為string中的字符','!返回迭代器!
cout << string(str_line.crbegin(),rcomma)<<endl;
cout << string(rcomma.base(),str_line.cend()) << endl; //reverse_iterator調(diào)用base成員函數(shù)广恢,返回其對(duì)應(yīng)的普通迭代器凯旋!
//鏈表類(lèi)型容器list和forward_list,應(yīng)優(yōu)先使用成員函數(shù)版本的算法钉迷!
//list提供雙向迭代器至非,forward_list提供前向迭代器。鏈表的獨(dú)有方法與通用版有所不同糠聪,如unique會(huì)刪除相同元素荒椭,而通用版本不會(huì)!
//lst.merge(lst2) 將lst2并入lst枷颊,合并后lst2為空戳杀。
//lst.merge(lst2,comp)
//lst.remove(val) 刪除元素(或滿(mǎn)足條件的元素)
//lst.remove_if(pred)
//lst.reverse() 反轉(zhuǎn)lst中的元素
//lst.sort() 使用<或給定操作排序元素
//lst.sort(comp)
//lst.unique()
//lst.unique(pred)
//splice和splice_after(args) args可以為p,lst2/p,lst2,p2/p,lst2,b,e將lst2的元素移動(dòng)到lst中!
system("pause");
return 0;
}
//標(biāo)準(zhǔn)庫(kù)并未給每個(gè)容器添加大量功能夭苗,而是提供一組算法,泛型算法隔缀!
//大多數(shù)算法都定義在頭文件algorithm题造,標(biāo)準(zhǔn)庫(kù)還在頭文件numeric中定義了一組數(shù)值泛型算法。