“泛型”指的是算法可以用于不同类型的元素和多种容器类型,是独立于容器的。
泛型算法通过迭代器间接访问容器,不会执行容器的操作,只运行在迭代器之上,迭代器可以做什么,泛型算法就可以做什么。
标准库提供了超过100个算法,但是都有规律可循。大部分都对一个范围内的元素进行操作,类似于algorithm(vec.begin(),vec.end(),…),前两个参数确定范围,后面的参数根据算法的作用确定。
使用泛型算法,必须加上头文件
#include
按三个部分介绍:“只读算法”、“写容器元素的算法”和“重排容器元素的算法”。
因为是只读算法,不影响容器内的元素,所以遍历时用cbegin()和cend()。
1. 查找算法find
auto result = find(iter1, iter2, val);
查找两个迭代器所指范围内是否存在val,若存在,返回对应元素的迭代器,若不存在,返回第二个参数,在此例中为iter2。
可以以返回值做判断:
if(result != iter2){//找到了
//```
}
else{}
同样可用于内置数组:
int ia[] = {...};
int cal = ...;
int* result = find(begin(ia), end(ia), val);
2. 计数算法count
auto result = count(iter1,iter2,val);
返回两个迭代器所指范围内val出现的次数。
3. 求和算法accumulate
type sum = accumulate(iter1, iter2, val);
返回两个迭代器所指范围内所有元素的和,和的初始值设置为val。
和的类型取决于定义的变量类型。
4. 比较算法equal
bool result = equal(c1.cbegin(),c1.cend(),c2.cbegin());
返回c1和c2两个序列的大小,前两个参数是c1序列的始末,第三个参数是c2序列的首元素。
必须保证第二个序列至少和第一个一样长。
1. 覆盖算法fill
fill(iter1, iter2, val);
将两个迭代器范围内的所有元素置为val。
fill_n(iter, n, val)
iter开始的序列至少包含n个val元素。
需要注意的是,默认前提是容器必须已经有至少n个元素,若是空的,就不能使用这个算法,相当于该语句未定义。
2. 插入迭代器back_inserter
在上面覆盖算法中,只能覆盖元素,不能插入,那怎么插入呢?
back_inserter是插入迭代器,通过此迭代器可以调用push_back往容器中添加元素。
fill_n(back_inserter(vec),n,val);
这样就相当于向vector容器中尾部添加n个val元素。
3. 拷贝算法copy
auto ret = copy(c1.begin(), c1.end(), c2.begin())
将前两个迭代器所指范围内的元素全部拷贝进c2容器中,返回拷贝的最后一个元素之后的位置。
必须保证第二个序列的长度大于第一个序列。
4. 替换算法replace
replace(iter1, iter2, val1, val2)
将两个迭代器所指范围内的val1都替换为val2。
1. 排序算法sort
sort(iter1, iter2)
将两个迭代器所指范围内的序列升序排列。降序排序的方法在定制操作里面介绍。
2. 去重算法unique
auto result = unique(iter1, iter2)
将两个迭代器所指范围内相邻的重复项消除,返回一个指向不重复值范围末尾的迭代器。
一般在sort排序之后使用。
3. 删除算法erase
auto result = erase(iter1,iter2)
将两个迭代器所指范围内的元素删除,返回删除的最后一个元素之后的迭代器。
在sort排序算法中,默认是按升序排列的,这个顺序是可以改的。
sort的另一个版本:
sort(itr1, itr2, 布尔函数)
当两个元素比较的时候,就会调用这个布尔函数。
举个例子:
bool order(int a, int b){
return a > b;
}
int main()
{
vector v = {1,3,2};
sort(v.begin(),v.end(),order);
}
order函数返回两个值比较的结果,也就是你想要的结果:降序。
如果sort调用order后返回个false,说明不满足order函数,就调换两个元素的顺序。