STL4.1 算法
即函数模板,用来对容器操作,在algorithm\numeric中定义
一、不变序算法
不会改变算法作用的容器或对象,适用于所有容器
1.常见算法
- min,max,min_element,max_element
- for_each
- count,count_if
- find,find_if,find_first_of,adjacent_find
- find_end,search
- search_n
- equal,mismatch
- lexicographical
2.例
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
void print(int v){
cout<<"<"<<v<<">";
}
bool lessthan4(int n){
return n<4;
}
int main(){
cout<<"1)"<<min(3,4)<<" "<<max(5,6)<<endl;
int a[9]={1,2,3,4,5,3,4,4,4};
cout<<"2)"<<*min_element(a,a+9)<<" "<<*max_element(a,a+9)<<endl;
cout<<"3)"<<count(a,a+9,4)<<" "<<count_if(a,a+9,lessthan4)<<endl;
list<int> lst(a,a+9);
int b[2]={4,3};
vector<int> v(b,b+2);
list<int>::iterator p;
p=find_first_of(lst.begin(),lst.end(),b,b+2);//找到4,3中任一元素
cout<<"4)"<<distance(lst.begin(),p)<<endl;
reverse(v.begin(),v.end());
int* ptr=find_end(a,a+9,v.begin(),v.end());
cout<<"5)"<<distance(a,ptr)<<endl;
p=adjacent_find(lst.begin(),lst.end());
cout<<"6)"<<*p<<" "<<distance(lst.begin(),p)<<endl;
p=search(lst.begin(),lst.end(),v.begin(),v.end());
cout<<"7)"<<distance(lst.begin(),p)<<endl;
ptr=search_n(a,a+9,2,4);
cout<<"8)"<<distance(a,ptr)<<endl;
cout<<boolalpha;//将true,false以字符串的形式输出
cout<<"9)"<<equal(v.begin(),v.end(),a+2)<<endl;
int c[6]={1,2,3,9,7,8};
pair<int*,int*> result;
result=mismatch(c,c+6,a);
cout<<"10)"<< *(result.first) <<" "<<*result.second<<endl;
cout<<"11)"<<lexicographical_compare(a,a+9,c,c+6)<<endl;
for_each(a,a+3,print);
return 0;
}
结果:
1)3 6
2)1 5
3)4 4
4)2
5)5
6)4 6
7)2
8)6
9)true
10)9 4
11)true
<1><2><3>
二、变值算法
1.修改源区间或目标区间中元素的值,值被修改的区间不应该属于关联容器,否则会改变有序性
2.例
#include <iostream>
#include <list>
#include<iterator>
#include <vector>
#include <algorithm>
using namespace std;
void modify(int & lst){lst*=lst;}
int square(int n){return n*n;}
int zero(){return 0;}
int one(){return 1;}
bool even(int n){return ! (n%2);}
int main(){
int a[6]={1,2,3,4,5,6};
int b[6];
copy(a,a+6,b);
ostream_iterator<int> oit(cout,",");
cout<<"1)";copy(b,b+6,oit);cout<<endl;
copy_backward(b,b+4,b+5);//源区间和目标区间有重叠,为了保证正确复制,倒着复制
cout<<"2)";copy(b,b+6,oit);cout<<endl;
list<int> lst(5);//预先开辟空间,否则复制操作会出错
transform(a,a+5,lst.begin(),square);
cout<<"3)";copy(lst.begin(),lst.end(),oit);cout<<endl;//a中元素没有改变
swap_ranges(lst.begin(),lst.end(),b);
cout<<"4)";copy(lst.begin(),lst.end(),oit);cout<<endl;//交换等长区间的内容
fill(b,b+6,0);
fill_n(b+2,3,1);
cout<<"5)";copy(b,b+6,oit);cout<<endl;
copy(a,a+6,b);
generate(b,b+6,zero);
generate_n(b+1,3,one);
cout<<"6)";copy(b,b+6,oit);cout<<endl;
replace(b,b+6,1,3);
cout<<"7)";copy(b,b+6,oit);cout<<endl;
replace_if(b,b+6,even,11);
cout<<"8)";copy(b,b+6,oit);cout<<endl;
replace_copy(a,a+6,b,3,30);
cout<<"9)";copy(b,b+6,oit);cout<<endl;
replace_copy_if(a,a+6,b,even,7);
cout<<"10)";copy(b,b+6,oit);cout<<endl;
return 0;
}
结果:
1)1,2,3,4,5,6,
2)1,1,2,3,4,6,
3)1,4,9,16,25,
4)1,1,2,3,4,
5)0,0,1,1,1,0,
6)0,1,1,1,0,0,
7)0,3,3,3,0,0,
8)11,3,3,3,11,11,
9)1,2,30,4,5,6,
10)1,7,3,7,5,7,
例子中copy的用法:
template <class _II,class _OT> _OI copy(_II _F,_II _L,_OT _X){
for(;_F!=_L;++_X,++_F)
*_X=*_F;
return (_X)
}
template<class T>
class myostream_iteraotr{
private:
ostream &os;//这里必须是ostream&
/*ostream os 不可以
因为ostream设计上是一个基类,它抽象了底层的行为,它本身什么功能都没有,当然不允许构造实例。
ostream *os = new ofstream();
作为基类指针完全可以。*/
string s;
public:
myostream_iteraotr(ostream &ot,string x):os(ot),s(x){}
void operator ++(){};
myostream_iteraotr & operator *(){
return *this;//返回自己本身,而不是自己的指针
}
myostream_iteraotr & operator=(const T x){
os<<x<<s;return *this;
}
};
三、删除算法
1.工作原理:
将应该删除的元素看成空位,将剩余元素从后往前移动,依次去填充这些空位,没有被填充的空位保持原来的值不变
不作用于关联容器
2.例
#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<iterator>
using namespace std;
bool lessthan4(int n){
return n<4;
}
int main(){
int m[5]={1,2,3,2,5};
ostream_iterator <int> oit(cout,",");
int *q=remove(m,m+5,2);
cout<<"1)";copy(m,m+5,oit);cout<<endl;
cout<<"2)"<<q-m<<endl;
int a[5]={1,2,3,2,5};
int b[6]={1,2,3,2,5,6};
int c[6]={0,0,0,0,0,0};
remove_if(b,b+6,lessthan4);
cout<<"3)";copy(b,b+6,oit);cout<<endl;
int *p=remove_copy(a,a+5,c,2);
cout<<"4)";copy(a,a+5,oit);cout<<" "<<p-c<<endl;
cout<<"5)";copy(c,c+6,oit);cout<<endl;
memset(c,0,sizeof(c));
remove_copy_if(a,a+5,c,lessthan4);
cout<<"6)";copy(c,c+6,oit);cout<<endl;
int d[7]={1,2,2,2,3,3,4};
vector<int> v;
v.insert(v.begin(),d,d+7);
unique(d,d+7);
cout<<"7)";copy(d,d+7,oit);cout<<endl;
memset(d,0,sizeof(d));
unique_copy(v.begin(),v.end(),d);
cout<<"8)";copy(d,d+7,oit);cout<<endl;
return 0;
}
结果:
1)1,3,5,2,5,
2)3
3)5,6,3,2,5,6,
4)1,2,3,2,5, 3
5)1,3,5,0,0,0,
6)5,0,0,0,0,0,
7)1,2,3,4,3,3,4,
8)1,2,3,4,0,0,0,