C++ 泛型算法

“泛型”指的是算法可以用于不同类型的元素和多种容器类型,是独立于容器的。
泛型算法通过迭代器间接访问容器,不会执行容器的操作,只运行在迭代器之上,迭代器可以做什么,泛型算法就可以做什么。
标准库提供了超过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函数,就调换两个元素的顺序。

你可能感兴趣的:(C++)