您的位置:首页 > 编程语言 > C语言/C++

C++STL之变异算法

2014-08-05 10:17 507 查看




1.复制

主要函数:

①copy

原型:template<classInIt,classOutIt>OutItcopy(InItfirst,InItlast,OutItx);

该函数功能是“正向---正向”拷贝,把输入迭代器[first,last)间的元素依次拷贝到输出迭代器x中,并返回输出迭代器的尾指针。

②copy_backward

原型:template<classBidIt1, class BidIt2> BidIt2copy_backward(BidIt1first, BidIt1 last, BidIt2 x);

该函数功能是“反向---反向”拷贝,把BidIt1中的(last,first]间元素依次拷贝到写双向迭代器x中,返回写功能输出迭代器的首指针。

copy简单示例

#include <iostream>
#include <vector>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5};
int b[5];
vector<int>v;
copy(a, a+5, b);
copy(a, a+5, back_inserter(v));
copy(a, a+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
copy(b, b+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


2.交换

主要函数

①swap

原型:template<classT>

voidswap(T&a,T&b);

两个相同模板参数类型变量的值互相交换。

②swap_ranges

原型:template<classFwdIt1, class FwdIt2>

FwdIt2
swap_ranges
(FwdIt1first, FwdIt1 last, FwdIt2 x);

该函数功能是:迭代器[first,last)间表示的容器A中元素依次与容器B中迭代器为x处开始的元素依次交换,并返回容器B中最后交换元素

的迭代器指针。

③iter_swap

原型:template<classFwdIt1, class FwdIt2>

void iter_swap(FwdIt1x, FwdIt2 y);
该函数功能是:交换两个前向迭代指针指向的元素值.

交换简单示例
<span style="font-size:14px;">#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
int a=10;
int b=20;
cout<<"原始a,b:"<<endl;
cout<<a<<"\t"<<b<<endl;
swap(a, b);
cout<<"交换后a,b:"<<endl;;
cout<<a<<"\t"<<b<<endl;
int a2[5]={1,2,3,4,5};
int b2[5]={6,7,8,9,10};
cout<<"原始数组a2:"<<endl;
copy(a2, a2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"原始数组b2:"<<endl;
copy(b2, b2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
swap_ranges(a2, a2+5, b2);
cout<<"交换后数组a2:"<<endl;
copy(a2, a2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"交换后数组b2:"<<endl;
copy(b2, b2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;

int a3[6]={10,20,30,40,50,60};
int b3[5]={15,25,35,45,55};
vector<int>v1(a3,a3+6);
vector<int>v2(b3,b3+5);
cout<<"原始v1:"<<endl;
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"原始v2:"<<endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
swap(v1,v2);
//   iter_swap(v1.begin(), v2.begin());
cout<<"交换后v1:"<<endl;
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"交换后v2:"<<endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}</span>


通过swap函数原型swap(T&a, T& b)可明确看出它相当于引用调用,其余两个函数swap_ranges、iter_swap相当于地址指针调用。因此示例中:基本数据类型swap(a,b)可以用iter_swap(&a,&b)代替;基本序列容器swap(v1,v2)可以用iter_swap(&v1,&v2)代替,当然从功能上说也可用swap_ranges(v1.begin(),v1.end(),
v2.begin())代替;但是对数组来说只能用swap_ranges,如示例那样。因此可以总结出:对于基本数据类型可用swap或iter_swap,对数组只能用swap_ranges,对基本序列容器三个函数均可。
3.变换

主要函数

①transform

原型:template<classInIt,classOutIt,classUnop>

OutIttransform(InItfirst,InItlast,OutItx,Unopuop);

template<class InIt1, classInIt2, classOutIt,classBinop>

OutIttransform(InIt1first1, InIt1 last1, InIt2 first2,OutIt x, Binopbop);

第一个模板函数功能是:一个输入迭代器容器每个元素依次做为一元函数uop参数传入并执行,结果输出到输出迭代器x表示的容器

中。即:*(x+N)=uop(*(first+N))。

第二个模板函数功能是:两个输入迭代器容器对应的一对元素做为二元函数bop参数传入并执行,结果输出到输出迭代器x表示的容器

中。即:*(x+N)=bop(*(first1+N),*(first2+N))。

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
int func1(int value)
{
return value*2;
}
int func2(int vlaue1,int value2)
{
return vlaue1+value2;
}
int main()
{
int a[5]={1,2,3,4,5};
vector<int>v1(a,a+5);
vector<int>v2(5);
vector<int>v3;
copy(a, a+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
transform(v1.begin(), v1.end(), v1.begin(), func1);
//  transform(v1.begin(), v1.end(), v1.begin(), bind2nd(multiplies<int>(),2));
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
transform(v1.begin(), v1.end(), v2.begin(), func1);
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
transform(v1.begin(), v1.end(), back_inserter(v3),func1);
copy(v3.begin(), v3.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;

int a2[5]={1,2,3,4,5};
int b2[5]={6,7,8,9,10};
int c2[5];
copy(a2, a2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
copy(b2, b2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
transform(a2, a2+5, b2, c2,func2);
// transform(a2, a2+5, b2, c2,plus<int>());
copy(c2, c2+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;

}


4.替换

主要函数

①replace

原型:template<caassFwdIt,class T>

void
replace
(FwdItfirst,FwdItlast,constT&vold,constT&vnew);

该函数功能是:遍历容器序列,若某元素等于旧值,则用新值代替。即: if(*(first+N)==vold)
*(first+N)=vnew

②replace_if

原型:template<classFwdIt,classPred,class T>

void
replace_if
(FwdItfirst,FwdItlast,Predpr,constT&val);

该函数功能是:if(pr(*(first+N))) *(first+N)=val;

③replace_copy

原型:template<classInIt,classOutIt,class T>

OutItreplace_copy(InItfirst,InItlast,OutItx,constT&vold,constT&vnew);

该函数功能是:

if (*(first + N) == vold) *(x + N) =vnew;

else *(x + N) = *(first + N)

④replace_copy_if

原型:template<classInIt,classOutIt,classPred,class T>

OutItreplace_copy_if(InItfirst,InItlast,OutItx,Predpr,constT&val);

该函数功能是:

if (pr(*(first+ N))) *(x + N) =val;

else *(x + N) = *(first + N)

4个replace函数简单示例

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
int a[9]={1,2,3,4,5,4,3,2,1};
cout<<"原始数据:"<<endl;
copy(a, a+9, ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"原数据2用10代替:"<<endl;
vector<int>v1(a,a+9);
replace(v1.begin(), v1.end(), 2, 10);
//replace(a, a+9, 2, 10);

copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"原始数据<4的用20代替:"<<endl;
vector<int>v2(a,a+9);
replace_if(v2.begin(), v2.end(), bind2nd(less<int>(), 4), 20);
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;

cout<<"原始数据4用30代替:"<<endl;
vector<int>v3(a,a+9);
vector<int>v4;
replace_copy(v3.begin(), v3.end(), back_inserter(v4), 4, 30);
copy(v4.begin(), v4.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;

cout<<"原始数据<4用40代替:"<<endl;
vector<int>v5(a,a+9);
vector<int>v6;
replace_copy_if(v5.begin(), v5.end(), back_inserter(v6), bind2nd(less<int>(), 4), 40);
copy(v6.begin(), v6.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


一个replace易犯错误示例
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[]={2,1,3,2,2,5};
replace(a, a+6, a[0], 10);
copy(a, a+6, ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


分析:void replace(FwdItfirst, FwdItlast,constT& vold,constT& vnew)
vold参数是引用调用,而非传值调用。对本例而言,初始时vold=2,按表意形式相当于:replace(a,a+6, 2, 10), 但当第一次发现数组中元素2,恰好是a[0],这样a[0]就变成10。由于是引用调用,相当于vold=10,这样当继续扫描数组a时,按表意形式相当于:replace(a+1,a+6, 10, 10), 因为vold= vnew=10,所以a数组后续元素不可能再发生变化。

5.填充

主要函数

①fill

原型:template<classFwdIt,class T>

void
fill(FwdItfirst,FwdItlast,constT& x);

该函数功能是:遍历容器中所有元素,每个元素都赋成值x。即:

*(first+ N)=x

②fill_n

原型:template<classOutIt,class Size, class T>

void
fill_n(OutItfirst, Size n, constT& x);

该函数功能是:遍历容器Size个元素,每个元素都赋成值x。即:

*(first+ N)=x

fill函数简单示例
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
int a[5];
fill(a, a+5, 0);
copy(a, a+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v1(5);
fill(v1.begin(), v1.end(),10);
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v2;
fill_n(back_inserter(v2),5,20);
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;

}


6.生成

主要函数

①generate

原型:template<classFwdIt,class Gen>

void generate(FwdItfirst,FwdItlast, Gen g);

该函数功能是:*(first+ N)=g()。

②generate_n

原型:template<classOutIt,classPred,class Gen>

void generate_n(OutItfirst,Distn, Gen g);

该函数功能是:*(first + N)=g(); N。

生成斐波拉契数列

<span style="font-size:14px;">#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Fibonacci
{
int f1;
int f2;
public:
Fibonacci(int start1,int start2):f1(start1),f2(start2){}
int operator()()
{
int r=f1+f2;
f1=f2;
f2=r;
return r;
}
};
int main()
{
vector<int>v1(10);
generate(v1.begin(), v1.end(), Fibonacci(0,1));
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
vector<int>v(20);
generate(v.begin(), v.end(), Fibonacci(0,1));
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<*(v.begin()+9)<<endl;
return 0;
}</span>


7.删除

主要函数

①remove

原型:template<classFwdIt,class T>

FwdItremove(FwdItfirst,FwdItlast,constT&val);

该函数功能是:首先设变量X= first,最终返回值是X。

if (!(*(first + N) == val))*X++ = *(first + N);

②remove_if

原型:template<classFwdIt,classPred>

FwdItremove_if(FwdItfirst,FwdItlast,Predpr);

该函数功能是:首先设变量X= first,最终返回值是X。

if (!pr(*(first+ N))) *X++ = *(first + N);

③remove_copy

原型:template<classInIt,classOutIt,class T>

OutItremove_copy(InItfirst,InItlast,OutItx,constT&val);

该函数功能是:

if (!(*(first + N) == val)) *x++ = *(first + N);

④remove_copy_if

原型:template<classInIt,classOutIt,classPred>

OutItremove_copy_if(InItfirst,InItlast,OutItx,Predpr);

该函数功能是:

if (!pr(*(first+ N))) *x++ = *(first + N);

remove简单示例

<span style="font-size:14px;">#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
int a[]={1,2,2,4,5,4,3,2,1};
vector<int>v(a,a+9);
sort(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
vector<int>::iterator first=v.begin();
vector<int>::iterator last;
last=remove(v.begin(),v.end(),2);
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
copy(v.begin(), last, ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}</span>


remove_copy简单示例
#include <iostream>
#include <vector>
#include <fstream>
#include <iterator>
#include <functional>
#include <algorithm>
using namespace std;
int main()
{
int a[]={1,2,3,4,5};
copy(a, a+5, ostream_iterator<int>(cout,"\t"));
cout<<endl;
vector<int>v(a,a+5);
vector<int>::iterator first=v.begin();
vector<int>::iterator last=remove_copy(v.begin(), v.end(), v.begin(), 3);
copy(first, last, ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v1(a,a+5);
vector<int>v2;
//  ofstream out("1.txt");
remove_copy(v1.begin(), v1.end(), back_inserter(v2), 3);
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
//  remove_copy(v2.begin(), v2.end(),ostream_iterator<int>(out,"\t"),1);
//  out.close();
cout<<endl;
return 0;
}


已知学生信息包含姓名、学号、语文及数学成绩,从学生集合中提取总成绩大于等于150分的学生信息并按文本格式存入文件中。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
class Student
{
public:
string name;
string NO;
int chinese;
int math;
public:
Student(){}
Student(string nam,string NO,int c,int m):name(nam),NO(NO),chinese(c),math(m){}
bool operator<(const int &total)const
{
return (chinese+math)<total;
}
};
bool MyCompare( const Student &s)
{
return s<150;
}
ostream &operator<<(ostream &os,const Student &s)
{
os<<s.name<<"\t"<<s.chinese<<"\t"<<s.math<<endl;
return os;
}
int main()
{
Student s1("zhang","1001",60,70);
Student s2("zadf","1002",70,80);
Student s3("terg","1003",75,85);
Student s4("qzng","1004",68,78);
Student s5("tyjh","1005",86,76);
Student s6("plop","1006",30,80);

vector<Student>v;
v.push_back(s1);
v.push_back(s2);
v.push_back(s3);
v.push_back(s4);
v.push_back(s5);
v.push_back(s6);

vector<Student>v2;
ofstream out("1.txt");
vector<Student>::iterator first=v.begin();
vector<Student>::iterator last=v.end();
remove_copy_if(first,last,ostream_iterator<Student>(out,"\t"), MyCompare);
copy(first,last,back_inserter(v2));
out.close();
copy(v2.begin(), v2.end(),ostream_iterator<Student>(cout,"\n"));
return 0;
}


8.唯一

主要函数

①unique

原型:template<classFwdIt>

FwdItunique(FwdItfirst,FwdItlast);

template<class FwdIt,classPred>

FwdItunique(FwdItfirst,FwdItlast,Predpr);

第1个模板函数先另X=first,返回值是X。

if (N == 0 || !(*(first + N) == V))

V =*(first + N), *X++ = V;

第2个模板函数先另X=first,返回值是X,与前一模板函数功能相近,只不过调用了一元判定函数。

if (N == 0 || !(pr(*(first+ N)) == V))

V =*(first + N), *X++ = V;

②unique_copy

原型:template<classInIt,classOutIt>

OutItunique_copy(InItfirst,InItlast,OutItx);

template<class InIt,classOutIt,classPred>

OutItunique_copy(InItfirst,InItlast,OutItx,Predpr);

第1个模板函数:if(N == 0 || !(*(first + N) == V))

V =*(first + N), *x++ = V;

第2个模板函数:if(N == 0 || !pr(*(first+ N), V))

V =*(first + N), *x++ = V;

unique函数简单示例

#include <iostream>
#include <vector>
#include <functional>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
int a[]={1,2,2,3,4,2,2,5};
vector<int>v(a,a+sizeof(a)/sizeof(int));
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
sort(v.begin(), v.end(), greater<int>());
vector<int>::iterator last=unique(v.begin(), v.end());
copy(v.begin(), last, ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v2;
sort(a, a+sizeof(a)/sizeof(int),greater<int>());
unique_copy(a,a+sizeof(a)/sizeof(int), back_inserter(v2));
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


9.反转

主要函数

①reverse

原型:template<classBidIt>

voidreverse(BidItfirst,BidItlast);

该函数功能是:在内部循环调用swap函数

swap(*(first + N), *(last - 1 - N))

②reverse_copy

原型:template<classBidIt,classOutIt>

OutItreverse_copy(BidItfirst,BidItlast,OutItx);

该函数功能是:*(x+ N) = *(last - 1 - N),返回x+(last-first)。

反转函数简单示例

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int a[]={1,2,3,4,5};
copy(a, a+sizeof(a)/sizeof(int), ostream_iterator<int>(cout,"\t"));
cout<<endl;
reverse(a, a+5);
copy(a, a+sizeof(a)/sizeof(int), ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v(a,a+5);
reverse(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;

vector<int>v2;
reverse_copy(a,a+5,back_inserter(v2));
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
reverse_copy(v2.begin(), v2.end(), v2.begin());
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


10.划分

主要函数

①partition

原型:template<classBidIt,classPred>

BidItpartition(BidItfirst,BidItlast,Predpr);

该函数功能是:容器元素重新定位,确定位置K。当0<N<K,pr(*(first+N))是true;当K<=N<last-first,pr(*(first+N))是false。函数最终返回first+ K。

②stable_partition

原型:template<classFwdIt,classPred>

FwdItstable_partition(FwdItfirst,FwdItlast,Predpr);

该函数功能是:与partition功能相似,只不过是稳定划分。若都满足条件,则原先在前面的元素当重新定位后仍在前面;若都不满足条件,则原先在前面的元素当重新定位后仍在前面。

划分函数简单示例
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
int main()
{
int a[]={1,7,2,5,3,4,8,2,3,6};
//   sort(a, a+10);
vector<int>v(a,a+10);
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"按<4划分(partition):"<<endl;
partition(v.begin(), v.end(),bind2nd(less<int>(),4));
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
cout<<"按4划分(stable_partition):"<<endl;
stable_partition(v.begin(), v.end(), bind2nd(less<int>(),4));
copy(v.begin(), v.end(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


已知学生信息包含姓名和成绩两项,把学生集合中成绩小于75分的放在容器的前面。

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
using namespace std;
struct Student
{
char name[20];
int grade;
};
bool GradeCmp(Student &s)
{
return s.grade<75;
}
ostream &operator<<(ostream &os,const Student &s)
{
os<<"("<<s.name<<"\t"<<s.grade<<")";
return os;
}
int main()
{
Student s[]={{"li1",79},{"li2",70},{"li3",68},{"li4",78},{"li5",65}};
copy(s, s+5, ostream_iterator<Student>(cout,"\t"));
cout<<endl;
vector<Student>v(s,s+5);
cout<<"不稳定划分(partition):"<<endl;
partition(v.begin(), v.end(),GradeCmp);
copy(v.begin(), v.end(), ostream_iterator<Student>(cout,"\t"));
cout<<endl;

cout<<"稳定划分(stable_partition):"<<endl;
vector<Student>v1(s,s+5);
stable_partition(v1.begin(), v1.end(),GradeCmp);
copy(v1.begin(), v1.end(), ostream_iterator<Student>(cout,"\t"));
cout<<endl;
return 0;

}


list容器划分
#include <iostream>
#include <list>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
int a[]={1,7,3,6,4,10,9,5,2,8};
list<int>v(a,a+10);
list<int>v2;
copy(v.begin(), v.end(),front_inserter(v2));
list<int>::iterator mid=stable_partition(v.begin(), v.end(),bind2nd(less<int>(),4));
copy(v.begin(), mid, ostream_iterator<int>(cout,"\t"));
cout<<endl;
int n=distance(v.begin(), mid);
cout<<n<<endl;

copy(v2.rbegin(), v2.rend(), ostream_iterator<int>(cout,"\t"));
cout<<endl;
return 0;
}


11.环移
12.随机
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: