- 大多数算法在
<algorithm>
。泛型算法运行在迭代器之上
auto result = find(vec.begin(), vec.end(), val);
int ia = [1, 2, 3];
int * result = find(begin(ia), end(ia));
数组利用指针实现泛型算法
- 只读算法:
find
、count
、accumulate, <numeric>里
、equal
- 迭代器参数:有的算法读取两个序列进行比较或转换,只需要容器中元素可以进行就行。所以
vector
和list
、int
和double
都可以的 - 写容器元素的算法:不做安全性检查、
back_inserter
可以改变容器大小,通过它赋值,就是插入、拷贝算法
vector <int> vec;
auto it = back_inserter(vec);
*it = 42; 相当于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()); //算法不能对容器进行操作
- 定制操作
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表达式:可能定义在函数的内部,必须使用尾置返回来指定返回类型。
[comture list一般为空,是lambda所在函数中定义的局部变量的列表] (parameter list) -> return type {function body}
。可以省略参数列表和返回类型。如果函数体包含除return
之外的语句,且未指定返回类型,则是void
stable_sort(words.begin(), words.end(), [] (const string &a, const string &b)
{return a.size()<b.size()} //长度短的在前面,返回true的在前面
- 一个
lambda
只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用变量
auto wc = find_if(words.begin(), words.end(), [sz](const string &a)
{ return a.size() >= sz; } ); //返回第一个长度不小于sz的元素的迭代器
- 捕获列表只用于局部非
static
变量,lambda
表达式可以直接使用局部static
变量和它所在函数之外的声明的变量
for_each(wc, words.end(), [] (const string &a) { cout << s << " ";});
-
可以这样理解,向函数传递一个
lambda
时,同时定义了一个新类型和该类型的一个对象:传递的参数就是这个未命名的对象 -
捕获分为值捕获和引用捕获。当使用引用方式捕获一个变量时,必须保证
lambda
在执行时是存在的。[a] or [&a]
-
值捕获也可以改变捕获的值,
mutable
[v1] () mutable {return ++v1};
- 隐式捕获:
[= or &]
让编译器推断捕获列表 - 混合捕获:
[=, &a]
默认的是值捕获,引用捕获需要显示捕获 - 参数绑定:
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的那些不是占位符的参数被拷贝到Bind返回的可调用对象中
//如果不能拷贝
ostream &print(ostream &os, const string &s, char c)
{
return os << s << c;
}
bind(print, ref(os), _1, ' '); //ref函数定义在<functional>, cref
- 插入迭代器:接受一个容器,生成一个迭代器,实现向给定容器添加元素
back_inserter : push_back
front_inserter : push_front
inserter : insert(it, val)
-
iostream
迭代器:istream_iterator
操作
istream_iterator<int> int_it(cin); //从cin中读取Int数据
istream_iterator<int> eof; //尾后迭代器
while (in_iter != eof)
vec.push_back(*in_iter++);
//或者从迭代器范围构造vec,当关联的流遇到文件尾或IO错误,迭代器的值就是eof
vector<int> vec(in_iter, eof)
//使用算法操作流迭代器
cout << accumulate(in, eof, 0)
-
ostream_iterator
的操作
ostream_iterator<int> out_iter(cout, " "); //在输出每个int后,输出" "
for(auto e : vec)
*out_iter++ = e; //等价于 out_iter = e
cout << endl;
//或者调用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() //++之后指向前一个元素
cr_test.base(); //装换为正向迭代器
-
迭代器类别:输入迭代器,
find
、输出迭代器,copy and ostream_iterator
、前向迭代器,replace
,可进行同一个位置的多次读写、双向迭代器,list的迭代器
、随机访问迭代器,array, deque, string, vector的迭代器
-
对于每个迭代器参数来说,其能力必须与规定的最小类别相当
-
算法命名规范
unique(beg, end);
unique(beg, end ,comp); //使用重载形式传递一个谓词
//_if
find(beg, end, val)
find(beg, end, pred) //返回第一个令pred为真的元素
//拷贝与不拷贝
reverse(beg, end);
reverse_copy(beg, end, dest)
- 特定容器的算法:是list和forward_list的成员函数算法,有的操作会改变容器
网友评论