- 大多數(shù)算法在
<algorithm>
坐漏。泛型算法運(yùn)行在迭代器之上
auto result = find(vec.begin(), vec.end(), val);
int ia = [1, 2, 3];
int * result = find(begin(ia), end(ia));
數(shù)組利用指針實(shí)現(xiàn)泛型算法
- 只讀算法:
find
鸽素、count
嗤锉、accumulate, <numeric>里
、equal
- 迭代器參數(shù):有的算法讀取兩個(gè)序列進(jìn)行比較或轉(zhuǎn)換,只需要容器中元素可以進(jìn)行就行。所以
vector
和list
砰碴、int
和double
都可以的 - 寫容器元素的算法:不做安全性檢查、
back_inserter
可以改變?nèi)萜鞔笮∮⒘耄ㄟ^它賦值哟绊,就是插入、拷貝算法
vector <int> vec;
auto it = back_inserter(vec);
*it = 42; 相當(dāng)于push_back()
int a1 = {1, 2, 3};
int a2[sizeof(a1)/sizeof(*a1)];
auto ret = copy(begin(a1), end(a1), a2); //<iterator>中的begin()
- 重排容器元素的算法
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end()); //算法不能對容器進(jìn)行操作
- 定制操作
bool isShorter(const string &s1, const string &s2)
{
return s1.size()<s2.size();
}
sort(words.begin(), words.end(), isShorter);
//如果想同等長度下门怪,按照字典順序
elimDups(words);
stable_sort(words.begin(), words.end(), isShorter);
- lambda表達(dá)式:可能定義在函數(shù)的內(nèi)部骡澈,必須使用尾置返回來指定返回類型。
[comture list一般為空掷空,是lambda所在函數(shù)中定義的局部變量的列表] (parameter list) -> return type {function body}
肋殴。可以省略參數(shù)列表和返回類型坦弟。如果函數(shù)體包含除return
之外的語句护锤,且未指定返回類型,則是void
stable_sort(words.begin(), words.end(), [] (const string &a, const string &b)
{return a.size()<b.size()} //長度短的在前面酿傍,返回true的在前面
- 一個(gè)
lambda
只有在其捕獲列表中捕獲一個(gè)它所在函數(shù)中的局部變量烙懦,才能在函數(shù)體中使用變量
auto wc = find_if(words.begin(), words.end(), [sz](const string &a)
{ return a.size() >= sz; } ); //返回第一個(gè)長度不小于sz的元素的迭代器
- 捕獲列表只用于局部非
static
變量,lambda
表達(dá)式可以直接使用局部static
變量和它所在函數(shù)之外的聲明的變量
for_each(wc, words.end(), [] (const string &a) { cout << s << " ";});
可以這樣理解赤炒,向函數(shù)傳遞一個(gè)
lambda
時(shí)氯析,同時(shí)定義了一個(gè)新類型和該類型的一個(gè)對象:傳遞的參數(shù)就是這個(gè)未命名的對象捕獲分為值捕獲和引用捕獲。當(dāng)使用引用方式捕獲一個(gè)變量時(shí)莺褒,必須保證
lambda
在執(zhí)行時(shí)是存在的掩缓。[a] or [&a]
值捕獲也可以改變捕獲的值,
mutable
[v1] () mutable {return ++v1};
- 隱式捕獲:
[= or &]
讓編譯器推斷捕獲列表 - 混合捕獲:
[=, &a]
默認(rèn)的是值捕獲遵岩,引用捕獲需要顯示捕獲 - 參數(shù)綁定:
bind
//在<functional>
bool check_size(const string &s, string::size_type sz)
{
return s.size() >= sz;
}
using std::placeholder::_1;
auto check6 = bind(check_size, _1, 6); //表示check6(_1) -> check_size(_1, 6)
//bind的那些不是占位符的參數(shù)被拷貝到Bind返回的可調(diào)用對象中
//如果不能拷貝
ostream &print(ostream &os, const string &s, char c)
{
return os << s << c;
}
bind(print, ref(os), _1, ' '); //ref函數(shù)定義在<functional>, cref
- 插入迭代器:接受一個(gè)容器你辣,生成一個(gè)迭代器,實(shí)現(xiàn)向給定容器添加元素
back_inserter : push_back
front_inserter : push_front
inserter : insert(it, val)
-
iostream
迭代器:istream_iterator
操作
istream_iterator<int> int_it(cin); //從cin中讀取Int數(shù)據(jù)
istream_iterator<int> eof; //尾后迭代器
while (in_iter != eof)
vec.push_back(*in_iter++);
//或者從迭代器范圍構(gòu)造vec,當(dāng)關(guān)聯(lián)的流遇到文件尾或IO錯(cuò)誤舍哄,迭代器的值就是eof
vector<int> vec(in_iter, eof)
//使用算法操作流迭代器
cout << accumulate(in, eof, 0)
-
ostream_iterator
的操作
ostream_iterator<int> out_iter(cout, " "); //在輸出每個(gè)int后宴凉,輸出" "
for(auto e : vec)
*out_iter++ = e; //等價(jià)于 out_iter = e
cout << endl;
//或者調(diào)用copy , std::copy, <algorithm>
copy(vec.begin(), vec.end(), out_iter);
cout << endl;
- 使用流迭代器處理類類型
istream_iterator<Sales_item> item_iter(cin), eof; //類定義了 <<
ostream_iterator<Sales_item> out_iter(cout, "\n"); //類定義了 >>
- 反向迭代器
vec.crbegin() //++之后指向前一個(gè)元素
cr_test.base(); //裝換為正向迭代器
迭代器類別:輸入迭代器,
find
蠢熄、輸出迭代器跪解,copy and ostream_iterator
、前向迭代器签孔,replace
叉讥,可進(jìn)行同一個(gè)位置的多次讀寫、雙向迭代器饥追,list的迭代器
图仓、隨機(jī)訪問迭代器,array, deque, string, vector的迭代器
對于每個(gè)迭代器參數(shù)來說但绕,其能力必須與規(guī)定的最小類別相當(dāng)
算法命名規(guī)范
unique(beg, end);
unique(beg, end ,comp); //使用重載形式傳遞一個(gè)謂詞
//_if
find(beg, end, val)
find(beg, end, pred) //返回第一個(gè)令pred為真的元素
//拷貝與不拷貝
reverse(beg, end);
reverse_copy(beg, end, dest)
- 特定容器的算法:是list和forward_list的成員函數(shù)算法救崔,有的操作會(huì)改變?nèi)萜?/li>