大多数都定义在头文件algorithm中,也有的在numeric。这些算法不依赖于容器,只要给迭代器就能运算,同时也不取决于元素类型,但和元素类型的运算符有关(比如== > <),对于没有自定义结构的元素类型,一般要进行重载运算符,才能使用泛型算法。
一、只读算法
1、find(it_begin,it_end,dst);//查找
其中it_begin为寻找范围中的第一个的迭代器,it_end为寻找范围中的最后一个的下一个的迭代器,dst为目标值。此函数也可以用于普通数组,但参数要换成第一个元素的地址,最后一个元素的下一个地址,可用begin(arr),end(arr)来计算这两个参数。
2、accumulate(it_begin,it_end,src);//累加
其中it_begin为累加范围中的第一个的迭代器,it_end为累加范围中的最后一个的下一个的迭代器,src为累加前初值。
3、equal(it1_begin,it1_end,it2_begin)//比较两个序列是否相同
二、写容器元素算法
fill(it_begin,it_end,val);//将it_begin()到it_end()之前的数都置为val
fill_n(it_begin,size,val);//将it_begin开始的size个数,置为val
(需要确保原来的容器有那么多个元素)
三、back_inserter插入迭代器
插入迭代器就是,每次往这个迭代器指向的位置赋值时候,都相当于push_back一个元素。
vector<int> vec; auto it = back_inserter(vec);//获取vec的插入迭代器 *it = 42;//插入第一个元素42 *it = 43;//插入第二个元素43
四、拷贝算法
1、copy(it1_begin,it1_end,it2_begin);
将范围1的值拷贝到it2_begin开始的容器。(前提:容器2有那么多位置)
2、replace(it_begin,it_end,0,42);
将序列中所有的0替换成42
3、 replace_copy
vector<int> vec;
replace_copy(it_cbegin,it_cend,back_inserter(vec),0,42);
不改变原序列,将所有值复制到vec中再把0改成42
五、重排容器元素的算法
1、sort(it_begin,it_end);
sort默认按从小到大的方式排序,也可以自定义一个接收两个形参,返回布尔值的函数,作为sort的第三的参数来定制排序规则。如果元素是自定义数据结构,需要在类里重载<运算符。
2、消除重复元素
先sort函数排序,再用unique函数,相当于把重复出来的元素都放到最后(同时这些元素不可访问)并返回有效元素中最后一个的迭代器,最后用erase将此迭代器到容器最末的所有元素删掉。
vector<int> arr{ 1 ,2,3,3,3,4,5,6,6,7,8 }; auto end_unique = unique(arr.begin(), arr.end());//确保了arr.begin()到end_unique前一个之间的所有元素是唯一的 arr.erase(end_unique, arr.end());//删掉end_unique到arr.end()后无效的元素。
六、特定容器算法
与其它容器不同,链表list和forward_list定义了几个成员函数形式的算法.特别是它们定义了独有的sort、merge、remove、reverse和unique。通用版本的sort要求随机访问迭代器,因此并不能用于list和forward_list,因为他们分别仅提供双向迭代器和前向迭代器。
七、lambda表达式
C++中一共有四种可调用对象:函数、函数指针、重载了函数调用运算符的类、lambda表达式。lambda可以理解为一个未命名的内联函数。
形式如下:
[capture list] (parameter list) ->return type { function body }
capture list是一个lambda所在函数中定义的局部变量的列表,空的capture list表明此lambda不使用所在函数中的任何局部变量,return type是返回类型,parameter list是形参列表,function body是函数体。
当无需形参时,可以忽略参数列表,当只有唯一确定的返回类型时,可忽略返回类型。
但必须永远包含capture list和function body。
auto f = [] { return 42; }; cout << f() <<endl;
例,find_if(it_begin,it_end,条件)//在序列中查找符合条件的元素的迭代器
find_if的第三个参数只能接收一元谓词,如果需要两个外部形参的话只能用lambda表达式写,并且其中一个参数要变成capture list里的捕获值,以调用其所在函数的局部变量。
比如我们要找出第一个长度大于sz的某字符串
sz = 5;
auto wc = find_if(it_begin,it_end,[sz] (const string &str) { return str.size() >= sz;} );
//获取第一个指向满足size大于sz的字符串的迭代器