标准库定义了一些通用算法(也就是泛型) 它可以用于第个容器上。不过容器有自己自带的算法,就使用容器自带的算法,因为效率会比通用的算法高。
大多数算法头文件都定义在头文件 algorthm 中,头文件 numeric中定义了 组数值泛型算法。
一般情况下这些算法不直接操作容器,而遍历两个迭代器指定的一个元素范围。
find 查找算法:
在容器 vec 中查找指定的元素,如果存在就返回结果指向它,不存在返回结果为 vec.cend();
上代码:
vector<int> v1 (100);
default_random_engine eran(time(0));
uniform_int_distribution<int> u(1,100);//随机生成1 到 100 之间的数字
for(auto i : v1 )
{
v1.push_back(u(eran));//将随机生成的数字放入容器中
}
auto numbers = find(v1.cbegin(),v1.cend(),1577);
if (numbers != v1.cend())
cout<<"找到了:"<<*numbers<<endl;
else {
cout<<"容器中没有这个元素!"<<endl;
}
算法永远不会改变底层容器的大小。但它可能改变容器中保存的元素的值,也可能在容器中移动元素,但永远不会直接添加或删除元素。
accumulate算法:
它定义在头文件 numeric 中,它接受三个参数,前面两个指出了需要求和的地元素的范围,第三个参数是和的初值。
//对容器 v1 中的元素求和, 和的初值是 0
int sum = accumulate(v1.cbegin(),v1.cend(), 0);
但它的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型。
vector<string> v2(2);
v2[0] = "This is";
v2[1] = "my phone!";
auto nums= accumulate(v2.cbegin(),v2.cend(),string("666"));
cout<<nums<<endl;
由于 string 定义了 + 运算符(要有 + 运算符的才可以使用),上面代码实现的作用就是把 v2 容器中的字符串全部连接起来:
这里注意一下:
vector <double> v5 ={3.14,3.12,3.4545};
auto nums = accumulate(v5.cbegin(),v5.cend(),0.0);
如果上面函数的第三个参数传入的是 0 ,那么输出结果也会被转换成整数 ,如果换成 0.0 ,那么输出结果就会输出小数,不过你转入 0.00 ,0.0000 和传入 0.0 是一样的,这个不会影响它计算结果的精度。
操作两个序列的算法 :equal
如果两个容器中的元素都对应相等,就返回 true ,否则就返回 false 。
vector<int> v1={1,2,3,4,5};
vector<int> v2={1,2,3,4,5};
cout<<boolalpha;//让 bool 类型的值输出为字符串形式
bool same = equal(v1.cbegin(),v1.cend(),v2.cbegin());//第三个参数传入另一个容器的首地址
cout<<same<<endl;
cout<<noboolalpha;
元素必须要对应相等才行,如果有一个不对应相等那么也会返回 false ,两个容器中的元素个数要是一样的(两个序列或容器要一样长或一样大)。
由于它是利用迭代器完成操作,我们可以通过它来比较两个不同类型的容器中的元素。
vector<string> v3={"t", "i","\0"};
list<char*> v4={"t", "i", "\0"};
bool same1 = equal(v3.cbegin(),v3.cend(),v4.cbegin());
我们要确保算法不会访问容器或序列中不存在的元素/空间。
算法 fill:
它接受三个参数,前两个表示操作范围,接受一个值作为第三个参数。
vector<int> v1={1,2,3,4,5};
fill(v1.begin(),v1.end(),10);//将容器 v1 中的元素全部替换成 10
fill_n:
它的用法直接看代码:
vector<int> v1={1,2,3,4,5};
fill_n(v1.begin(),3,100);
它的用法是 :第一个参数作为起始位置, 第二个参数代表从第一个参数位置开始数后面的 n 个位置。第三个参数是一个值。
上面代码的意思就是把 v1 容器中从第一个元素开始到第三个元素把它们替换成 100。
注意:算法不检查写操作。
我们不用在一个空的容器上调用 fill_n ,也在不能在空容器上使用类似写操作的算法。
vector<int> v2;
fill_n(v2.begin(), 2, 1000);//修改容器中不存在的 2 个元素
这是一个严重的错误,编译器不会报错。
向目的位置迭代器写入数据的算法应该保证目的位置足够大,能够容纳要定入的元素。