先说一下STL操作的区间是 [a, b),左边是闭区间,右边是开区间,这是STL的特性,所以<algorithm>里面的函数操作的区间也都是 [a, b)。
algorithm的意思是算法,<algorithm>提供了很多算法,下面说一下常用的
先声明一下, sort()函数在这篇文章中没讲,因为sort()函数功能比较强大(我自己认为的,哈哈),所以我会专门用另一篇文章来讲sort()函数
1. max(x,y) 返回x、y中最大的那个
min(x,y) 返回x、y中最小的那个
abs(x) 返回x的绝对值
swap(x,y) 交换x、y的值
2. reverse(it,it+10);有两个参数;将区间 [it, it+10)内的元素翻转,it可以是数组也可以是顺序容器的迭代器;有一个地方要特别注意reverse()
中第一个参数指向第一个元素,第二个元素指向末尾元素的下一个位置,具体用法看代码
#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; int main() { int a[]={1,2,3,4,5,6,7,8,9,10}; string str="abcdefgh"; //string也是一种顺序容器,有各种成员函数,只不过它只能用来存放字符, vector<int> v; v.push_back(11); v.push_back(12); v.push_back(13); v.push_back(14); v.push_back(15); v.push_back(16); cout<<"翻转前:\n"; for(int i=0;i<10;i++) cout<<a[i]<<" "; cout<<"\n"; for(int i=0;i<str.size();i++) cout<<str[i]<<" "; cout<<"\n"; for(int i=0;i<v.size();i++) cout<<v[i]<<" "; cout<<"\n"; reverse(a,a+10); //操作区间为[a,b),reverse()中第一个参数指向第一个元素,第二个元素指向末尾元素的下一个位置 reverse(str.begin(),str.end()); reverse(v.begin(),v.end()); cout<<"翻转后:\n"; for(int i=0;i<10;i++) cout<<a[i]<<" "; cout<<"\n"; for(int i=0;i<str.size();i++) cout<<str[i]<<" "; cout<<"\n"; for(int i=0;i<v.size();i++) cout<<v[i]<<" "; cout<<"\n"; return 0; }
结果如下:
3. find(it, it+10, x);有三个参数;前两个参数为查找区间,第三个参数为待查找元素,即在[a, b)这个区间内查找x;find()和reverse()一样,操作的对象
可以是数组,也可以是容器;查找成功返回对应元素的位置,即若操作对象是数组就返回指针,指针指向对应元素的位置,若操作对象是容器就返回
迭代器,迭代器向对应元素的位置;查找不成功返回第二个参数的值。具体用法还是看代码吧,由于我写的比较详细,代码有点多,耐心点看
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 int main() 7 { 8 int a[]={1,2,3,4,5,6,7,8,9,10}; 9 string str("abcdefgh"); //string也是一种顺序容器,有各种成员函数,只不过它只能用来存放字符, 10 vector<int> v; 11 v.push_back(11); 12 v.push_back(12); 13 v.push_back(13); 14 v.push_back(14); 15 v.push_back(15); 16 v.push_back(16); 17 int* p1=find(a,a+10,8); //在[a,a+10)这一区间查找 18 int* p2=find(a,a+10,12); //a中不存在12,查找失败;只是为了展示一下查找失败是什么样子 19 int* p3=find(a,a+5,5); //在[a,a+5)这一区间查找;只是想说明可以任意的合法区间内查找 20 int* p4=find(a,a+5,7); //在[a,a+5)这一区间内不存在6,查找失败 21 string::iterator iter1=find(str.begin(),str.end(),'d'); 22 string::iterator iter2=find(str.begin(),str.end(),'m'); //str中不存在'm',查找失败 23 vector<int>::iterator iter3=find(v.begin(),v.end(),14); 24 vector<int>::iterator iter4=find(v.begin(),v.end(),17); //v中不存在17,查找失败 25 26 cout<<"在区间[a,a+10)内查找8:查找成功\n"; 27 cout<<"p1的值:"<<p1<<" a[7]的地址"<<&a[7]<<"\n"; //查找成功后,p1指向a[4],p1的值就是a[4]地址,这里就是为了验证p1是否等于&a[4] 28 cout<<"*p1="<<*p1<<" a[7]="<<a[7]<<"\n\n"; //输出p1所指的元素 29 30 cout<<"在区间[a,a+10)内查找12:查找失败\n"; 31 cout<<"p2的值:"<<p2<<" a+10的地址:"<<a+10<<"\n"; //查找失败后,返回第二个参数的值,这里就是为了验证p2是否等于a+10 32 cout<<"*p2="<<*p2<<"\n\n"; //由于返回了第二个参数的值,p2此时指向数组a末尾元素的下一个位置(即a+10),所以此时输出的*p2会是非法值 33 34 cout<<"在区间[a,a+5)内查找5:查找成功\n"; 35 cout<<"p3的值:"<<p3<<" a[4]的地址"<<&a[4]<<"\n"; //和上面的差不多,只是想说明可以是任意的合法区间 36 cout<<"*p3="<<*p3<<" a[4]="<<a[4]<<"\n\n"; //输出p3所指的元素 37 38 cout<<"在区间[a,a+5)内查找6:查找失败\n"; 39 cout<<"p4的值:"<<p4<<" a+5的地址:"<<a+5<<"\n"; //查找失败后,返回第二个参数的值,这里就是为了验证p2是否等于a+5 40 cout<<"*p4="<<*p4<<" a[5]="<<a[5]<<"\n\n"; //返回第二个参数的值后,p4的值就是a+5,p4指向a[5],此时输出的*p4就是a[5]的值 41 42 cout<<"在str里查找'd':查找成功\n"; 43 cout<<"*iter1="<<*iter1<<"\n"; //查找成功,输出迭代器所指元素 44 cout<<"结果为1代表查找失败,为0代表查找成功:"<<(iter1==str.end())<<"\n\n";//在这里判断一下是否查找成功 45 cout<<"在str里查找'm':查找失败\n"; 46 cout<<"结果为1代表查找失败,为0代表查找成功:"<<(iter2==str.end())<<"\n\n"; //查找失败,返回str.end()的值,即iter2指向str末尾元素的下一个位置,在这里也做个判断 47 48 cout<<"在v里查找14:查找成功\n"; 49 cout<<"*iter3="<<*iter3<<"\n"; //查找成功,输出迭代器所指元素 50 cout<<"结果为1代表查找失败,为0代表查找成功:"<<(iter3==v.end())<<"\n\n";//在这里判断一下是否查找成功 51 cout<<"在v里查找17:查找失败\n"; 52 cout<<"结果为1代表查找失败,为0代表查找成功:"<<(iter4==v.end())<<"\n"; //查找失败,返回str.end()的值,即iter2指向str末尾元素的下一个位置,在这里也做个判断 53 54 return 0; 55 }
结果看图:
4. fill(it,it+10,x);前两个参数为填充区间,第三个参数为待填充的数据,可以是任意数值;可以将数组it的[a,b)这一区间填充为x,或者对容器进行填充。
具体用法还是看代码吧
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 int main() 7 { 8 int a[]={1,2,3,4,5,6,7,8,9,10}; 9 string str("abcdefgh"); //string也是一种顺序容器,有各种成员函数,只不过它只能用来存放字符, 10 vector<int> v; 11 v.push_back(11); 12 v.push_back(12); 13 v.push_back(13); 14 v.push_back(14); 15 v.push_back(15); 16 v.push_back(16); 17 18 cout<<"数组a填充前:"; 19 for(int i=0;i<10;i++) 20 cout<<a[i]<<" "; 21 cout<<"\n数组a填充后:"; 22 fill(a+3,a+8,0); //指定填充区间 23 for(int i=0;i<10;i++) 24 cout<<a[i]<<" "; 25 cout<<"\n\n"; 26 27 cout<<"str填充前:"; 28 for(int i=0;i<str.size();i++) 29 cout<<str[i]<<" "; 30 cout<<"\nstr填充后:"; 31 fill(str.begin()+2,str.end()-1,'x'); //用迭代器指定填充区间 32 for(int i=0;i<str.size();i++) 33 cout<<str[i]<<" "; 34 cout<<"\n\n"; 35 36 cout<<"v填充前:"; 37 for(int i=0;i<v.size();i++) 38 cout<<v[i]<<" "; 39 cout<<"\nv填充后:"; 40 fill(v.begin()+1,v.end(),6); //用迭代器指定填充区间 41 for(int i=0;i<v.size();i++) 42 cout<<v[i]<<" "; 43 cout<<"\n"; 44 return 0; 45 }
运行结果看图:
5. copy(v1.begin(),v1.end(),v2.begin());copy()用于容器之间的复制,返回一个迭代器,这个迭代器指向v2中已被复制区间的最后一个位置;前两个参数是v1的复制区间,
把容器v1中[a,b)区间内的元素复制到容器v2中;第三个参数是复制到v2的起始位置(起始位置可以设置成任意合法的位置,不能越界),会覆盖掉v2对应区间的数据。特别要注意,
区间[a,b)的长度一定要小于 v2的复制起始位置到v2的末尾位置的长度,否则v2会溢出,运行结果会报错。
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 int main() 6 { 7 vector<int> v1,v2; 8 v1.push_back(1); 9 v1.push_back(2); 10 v1.push_back(3); 11 v1.push_back(4); 12 v2.push_back(11); 13 v2.push_back(12); 14 v2.push_back(13); 15 v2.push_back(14); 16 v2.push_back(15); 17 v2.push_back(16); 18 19 vector<int>::iterator iter,it; 20 cout<<"复制前v2中的元素:"; 21 for(it=v2.begin();it!=v2.end();it++) 22 cout<<*it<<" "; 23 iter=copy(v1.begin(),v1.end(),v2.begin()+1),it; //前两个参数指定复制区间,第三个参数指定v2的起始位置;返回迭代器,指向v2中被复制过来的最后一个元素的下一个位置 24 cout<<"\n把v1复制到v2中后,v2中的元素:"; 25 for(it=v2.begin();it!=v2.end();it++) 26 cout<<*it<<" "; 27 cout<<"\n*iter="<<*iter<<"\n"; //iter指向v2中被复制过来的最后一个元素的下一个位置 28 return 0; 29 }
结果如下图:
下面来验证一下我上面说过的 “区间[a,b)的长度一定要小于 v2的复制起始位置到v2的末尾位置的长度,否则v2会溢出,运行结果会报错”(一定要理解这句话,可以自已去试试),
为此我把v2改了一下,把v2长度改短了。看代码
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 int main() 6 { 7 vector<int> v1,v2; 8 v1.push_back(1); 9 v1.push_back(2); 10 v1.push_back(3); 11 v1.push_back(4); 12 v2.push_back(11); 13 v2.push_back(12); 14 v2.push_back(13); 15 16 vector<int>::iterator iter,it; 17 cout<<"复制前v2中的元素:"; 18 for(it=v2.begin();it!=v2.end();it++) 19 cout<<*it<<" "; 20 iter=copy(v1.begin(),v1.end(),v2.begin()+1),it; //前两个参数指定复制区间,第三个参数指定v2的起始位置;返回迭代器,指向v2中被复制过来的最后一个元素的下一个位置 21 cout<<"\n把v1复制到v2中后,v2中的元素:"; 22 for(it=v2.begin();it!=v2.end();it++) 23 cout<<*it<<" "; 24 cout<<"\n*iter="<<*iter<<"\n"; //iter指向v2中被复制过来的最后一个元素的下一个位置 25 return 0; 26 }
结果如下:
可以看到程序还没运行完就报错了,所以一定要注意这一点。