变异算法
(1) 复制
copy():从序列的第一个元素起进行正向复制。
原型:
template<class InIt,class OutIt>
OutIt copy(InIt first,InIt last,OutIt x);
参数说明: 模板参数InIt表示输入迭代器,OutIt表示输出迭代器
返回值类型是OutIt,是输出迭代器的尾指针。
该函数的功能是“正向--正向”复制,把输入迭代器[first,last)间的元素依次复制到输出迭代器x中,并返回输出迭代器的尾指针。
copy_backward() :从序列的最后一个元素起进行反向复制。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a[]={1,2,3,4,5};
int b[5];
vector<int>v;
copy(a,a+5,b);
copy(a,a+5,back_inserter(v));
cout<<"原始a数组为:";
copy(a,a+5,ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"b数组为:";
copy(b,b+5,ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"vector向量为:";
copy(v.begin(),v.end(),ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}
1、copy函数非常简洁,只要给出源数据待复制区间的迭代起止指针及输出迭代器起始指针就可以了。
注意:[first,last),左边是闭区间,右边是开区间。所以上例中a数组全部复制到b数组一定是copy(a,a+5,b)而不能是copy(a,a+4,b)
2、若目的数据类型是数组,则一定要保证它的内存空间大于或等于源待复制数据空间的大小。
若目的数据类型是基本序列容器vector、list等,则由于可通过back_inserter,front_inserter插入迭代器动态改变容器的大小,因此对基本序列容器对象内存空间没有特殊限制。 但上例若不用back_inserter,直接写成copy(a,a+5,v),则编译通不过。
3、copy语义非常丰富。例如本题中可以数组复制到数组、数组复制到基本序列容器、数组复制到屏幕、基本序列容器数据复制到屏幕。 此时STL预定义迭代器ostream_iterator及istream_iterator起着很重要的作用。若把键盘输入的整型数存放到某vector对象vec中,可写为copy(istream<int>cin,istream_iterator<int>(),back_inserter(vec))。
(2)交换
swap():交换两个元素。
原型:
template<class T>
void swap(T& a,T& b);
两个相同模板参数类型变量的值互相交换。
swap_ranges() :交换指定范围的元素。
iter_swap(): 交换由迭代器所指的两个元素。
注意:
1、可以看出交换函数可以应用杂基本数据类型之间、数组之间、基本序列容器之间。
2、swap函数相当于引用调用,其余两个函数swap_ranges、iter_swap相当于地址指针调用。 基本数据类型swap(a,b)可以用iter_swap(&a,&b)代替
总结:对于基本数据类型可用swap或iter_swap,对数组只能用swap_ranges,对基本序列容器三个函数均可。
3、对数组而言,要交换的必须是真实的内存空间,因为对定义好的数组而言,它的大小是固定的,不可能动态变化,因此int[5]全部数据不能与int[7]的全部数据交换;
但是,对基本序列容器而言,由于它支持元素空间动态分配,因此相交换的容器拥有的元素内存空间可以是不同的,以下代码是正确的:
int a[5]={1,2,3,4,5};
int b[3]={6,7};
vector<int>v1(a,a+5);
vector<int>v2(b,b+2);
swap(v1,v2);
v1有5个元素,v2有2个元素;交换后v1有2个元素,v2有5个元素。
(3) 变换
transform() :将某操作应用与指定范围的每个元素。
函数原型:
template<class InIt,class OutIt,class Unop>
OutIt transform(InIt first,InIt last,OutIt x,Unop uop);
功能:一个输入迭代器容器中每个元素依次作为一元函数uop参数传入并执行,结果输出到输出迭代器x表示的容器中。
template<class InIt1,class InIt2,class OutIt,class Binop>
OutIt transform(InIt1 first1,InIt1 last1,InIt2 first2,OutIt x,Binop bop);
功能:两个输入迭代器容器对应的一对元素作为二元函数bop参数传入并执行,结果输出到输出迭代器x表示的容器中。
参数说明: InIt、OutIt:输入输出迭代器
Unop :一元函数
Binop :二元函数
示例:
int func1(int value)
{
return value*2;
}
int func2(int value1,int value2)
{
return value1+value2;
}
int a[5]={1,2,3,4,5};
vector<int>v1(a,a+5);
vector<int>v2(5); //v2初始容器大小有5个int元素
transform(v1.begin(),v1.end(),v1.begin(),func1); //调用一元函数,并且修改自己
transform(v1.begin(),v1.end(),v2.begin(),func1); //调用一元函数,形成新的集合
如果在v2的定义时,改为:vector<int>v2;其余不变,虽然编译通过,但是执行会出错。
此时需要将调用函数修改为 transform(v1.begin(),v1.end(),back_inserter(v2),func1);
(4) 替换
replace() : 用一个给定值替换一些值
原型: template<class FwdIt,class T>
void replace(FwdIt first,FwdIt last,const T& vold,const T& vnew);
参数说明:FwdIt:前向迭代器
T:容器元素类型
功能:遍历容器序列,若某元素等于旧值,则用新值替换。
replace_if() :替换满足谓词的一些元素
replace_copy():复制序列时用一给定值替换元素
replace_copy_if():复制序列时替换满足谓词的元素