一、只读算法:
1.计算求和:accumulate
头文件:numeric
函数接受三个参数,前两个参数是需要求和的元素范围,第三个参数是和的初始值,示例如下:
//对于只读取不改变元素的算法,通常使用cbegin()和cend()
int sum = accumulate(v.cbegin(),vec.cend(),0);
表示求v中所有元素的和,和的初始值为0.
因此可以应用到int、double、float等类型,另外因为string类型定义了“+”运算符,所以可以用该算法将vector中的string相连,示例如下:
string sum = accumulate(v.cbegin(),v.cend(),string(""));
string sum = accumulate(v.cbegin(),v.cend(),""); //编译错误
这里的第三个参数显示的创建了一个string,如果直接使用空串做为第三个参数会导致编译错误,因为const char*并没有+运算符。
2.确定两个序列是否保存相同的值:equal
它将第一个序列中的每个元素与第二个序列中的对应进行比较,如果所有元素都相等,则返回true,否则返回false。
函数接受三个参数,前两个表示第一个序列中的元素范围,第三个表示第二个序列的首元素,示例如下:
//v2的元素数目应该至少和v1一样多
equal(v1.cbegin(),v1.cend(),v2.cbegin());
可以用这个函数来比较不同类型的容器中的不同类型的元素,比如vector<string>和list<const char*>.
二、写容器元素的算法:
一些算法将新值赋予序列中的元素,算法本身是不会执行容器操作的,因此他们自身不会改变容器大小。
1.将元素重置:fill
fill函数接受一对迭代器表示范围,还接受一个值表示第三个参数。将给定的这个值赋予输入序列的每个元素:
fill(v.begin(),v.end(),0); //将每个元素重置为0
fill(v.begin(),v.begin() + v.size() / 2,10); //将一部分重置为10
2.返回与容器绑定的后置插入迭代器:back_inserter
头文件:iterator.h
接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器,使用此迭代器赋值时,复制运算符会调用push_back将一个具有给定值的元素添加到容器中,示例:
vector<int> vec; //空向量
auto it = back_inserter(vec); //通过它赋值会将元素添加到vec中
*it = 42; //这样就插入到vec中了
三、拷贝算法
1.向目的位置迭代器指向的输出序列中的元素写入数据:copy
此算法接受三个迭代器,前两个表示输入范围,第三个表示目的序列的起始位置,目的序列的长度上至少与输入序列相等。实例如下:
int a1[] = {0,1,2,3,4,5};
int a2[sizeof(a1)/sizeof(*a1)]; //a2与a1大小相同
auto ret = copy(begin(a1),end(a1),a2); //拷贝,ret指向a2尾元素之后的位置
2.替换指定的值:replace
replace算法接受四个参数,前两个参数表示范围,第三个参数表示指定的值,第四个参数是替换的值,实例如下:
replace(v.begin(),v.end(),0,1); //将所有值为0的元素改为值是1
如果希望保留原序列不变,可以调用replace_copy:
replace_copy(v.cbegin(),v.cend(),back_inserter(ivec),0,42);
四、重排容器的算法
1.排序:sort
重排序列中元素,使之有序,他是利用元素类型的<运算符来实现排序的:
sort(v.begin(),v.end());
2.不重复显示:unique
unique使得序列中的重复元素被覆盖,但并不是删除掉这些元素,调用完成后,返回指向最后一个不重复元素的后一个位置:
//指向最后一个不重复的元素后的位置,并未删除元素和改变序列长度
auto end_unique = unique(v.begin(),v.end());
//使用向量操作erase删除元素
v.erase(end_unique,v.end());