【C++ STL 温故而知新 002】中各种算法解析和string类

一、中各种算法解析

一,巡防算法

        for_each(容器起始地址,容器结束地址,要执行的方法)

[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <vector>  
  4.   
  5. using namespace std;  
  6.   
  7. template<class T>  
  8. struct plus2  
  9. {  
  10.     void operator()(T&x)const  
  11.     {  
  12.         x+=2;  
  13.     }  
  14.       
  15. };  
  16.   
  17. void printElem(int& elem)  
  18. {  
  19.   cout << elem << endl;  
  20. }  
  21.   
  22.   
  23. int main()  
  24. {  
  25.     int ia[]={0,1,2,3,4,5,6};  
  26.     for_each(ia,ia+7,printElem);//输出  
  27.       
  28.     int ib[]={7,8,9,10,11,12,13};  
  29.     vector<int> iv(ib,ib+7);  
  30.     for_each(iv.begin(),iv.end(),plus2<int>());//更改元素  
  31.     for_each(iv.begin(),iv.end(),printElem);//输出  
  32.       
  33.       
  34.     return 0;  

二,find算法

   int *find(int *begin,int *end,int  value)

   前闭后合的区间 begin,end中,查找value如果查找到了就返回第一个符合条件的元素,否则返回end指针

[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3.   
  4. using namespace std;  
  5.   
  6. void printElem(int& elem)  
  7. {  
  8.   cout << elem << endl;  
  9. }  
  10.   
  11.   
  12. int main()  
  13. {  
  14.     int ia[]={0,1,2,3,4,5,6};  
  15.       
  16.     int *ifind(ia,ia+7,9);//在整个数组中查找元素 9   
  17.     int *jfind(ia,ia+7,3);//在整个数组中查找元素 3  
  18.     int *end=ia+7;//数组最后位置   
  19.     if(i == end)   
  20.        cout<<"没有找到元素 9"<<endl;  
  21.     else   
  22.        cout<<"找到元素9"<<endl;  
  23.          
  24.     if(j == end)   
  25.        cout<<"没有找到元素 3"<<endl;  
  26.     else   
  27.        cout<<"找到元素"<<*j<<endl;  
  28.     return 0;  

三,数值算法

        包含在头文件中

[html] view plain copy
  1. #include <iostream>  
  2. #include <numeric>  //数值算法   
  3. #include <vector>  
  4. #include <functional>   
  5. #include <iterator>   
  6.   
  7. #include <math.h>   
  8.  using namespace std;  
  9.    
  10.  int main()  
  11.  {  
  12.     int ia[]={1,2,3,4,5};  
  13.     vector<int> iv(ia,ia+5);  
  14.       
  15.     cout<<accumulate(iv.begin(),iv.end(),0)<<endl; //累加  初值为0   
  16.     cout<<accumulate(iv.begin(),iv.end(),0,minus<int>())<<endl; //累加 符号位负  
  17.        
  18.     cout<<inner_product(iv.begin(),iv.end(),iv.begin(),10)<<endl;//两个数组内积  初值为10   
  19.     cout<<inner_product(iv.begin(),iv.end(),iv.begin(),10,minus<int>(),plus<int>())<<endl;//10-(1+1)-(2+2)  
  20.       
  21.     ostream_iterator<int> oite(cout," ");//迭代器绑定到cout上作为输出使用  
  22.     partial_sum(iv.begin(),iv.end(),oite);//依次输出前n个数的和   
  23.       
  24.     cout<<endl;   
  25.     partial_sum(iv.begin(),iv.end(),oite,minus<int>());//依次输出第一个数减去(除第一个数外到当前数的和)  
  26.       
  27.     cout<<endl;   
  28.     adjacent_difference(iv.begin(),iv.end(),oite); //输出相邻元素差值 前面-后面  
  29.       
  30.     cout<<endl;   
  31.     adjacent_difference(iv.begin(),iv.end(),oite,plus<int>()); //输出相邻元素差值 前面+后面  。前面更改影响后面元素   
  32.        
  33.        
  34.     cout<<endl;   
  35.     cout<<pow(10,3)<<endl; // 平方  
  36.       
  37.     /*  VC 不支持   只有安装了才SGI STL支持   
  38.     int n=3;  
  39.     iota(iv.begin(),iv.end(),n);//在指定区间填入n  n+1 n+2  
  40.     for(int i=0;i<iv.size();++i)  
  41.         cout<<iv[i]<<" ";   
  42.           
  43.         */   
  44.     return 0;  
  45.  }  
  46.   

四,基本算法

[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <vector>  
  4.   
  5. using namespace std;  
  6.   
  7. template<typename T>  
  8. struct display  
  9. {  
  10.     void operator()(const T  &x)const  
  11.     {  
  12.         cout<<x<<" ";  
  13.     }  
  14.       
  15. };  
  16.   
  17.   
  18. int main()  
  19. {  
  20.     int ia[]={0,1,2,3,4,5,6,7,8};  
  21.     vector<int> iv1(ia,ia+5);  
  22.     vector<int> iv2(ia,ia+9);  
  23.       
  24.     pair<vector<int>::iterator,vector<int>::iterator> pa;  
  25.     pa=mismatch(iv1.begin(),iv1.end(),iv2.begin());  
  26.     cout<<"两个数组不同点--第一个数组点:"<<*(pa.first)<<endl; //这样写很危险,应该判断是否到达end   
  27.     cout<<"两个数组不同点--第二个数组点:"<<*(pa.second)<<endl;  
  28.       
  29.     //更改之后  
  30.     if(pa.first == iv1.end())  
  31.         cout<<"第一个数组与第二个数组匹配"<<endl;   
  32.           
  33.     cout<<equal(iv1.begin(),iv1.end(),iv2.begin())<<endl;// 1 表示 相等,因为只比较跟 iv1长度大小的数组   
  34.     cout<<equal(iv1.begin(),iv1.end(),&ia[3])<<endl;// 0 表示 不相等   
  35.     cout<<equal(iv1.begin(),iv1.end(),&ia[3],less<int>())<<endl;// 1 表示 前者小于后者  
  36.       
  37.     fill(iv1.begin(),iv1.end(),9);//将iv1区间内填满 9  
  38.     for_each(iv1.begin(),iv1.end(),display<int>());  
  39.     cout<<endl;     
  40.       
  41.     fill_n(iv1.begin(),3,6);//从iv1区间开始填 3个6   
  42.     for_each(iv1.begin(),iv1.end(),display<int>());  
  43.     cout<<endl;  
  44.       
  45.       
  46.     vector<int>::iterator ite1=iv1.begin();  
  47.     vector<int>::iterator ite2=ite1;  
  48.     advance(ite2,3);//向前跳3个  
  49.       
  50.     iter_swap(ite1,ite2);//交换迭代器指向的元素  
  51.     for_each(iv1.begin(),iv1.end(),display<int>());  
  52.        
  53.     cout<<"\nmax:"<<max(*ite1,*ite2)<<endl;  
  54.     cout<<"min:"<<min(*ite1,*ite2)<<endl;  
  55.       
  56.     swap(*ite1,*ite2);  
  57.     for_each(iv1.begin(),iv1.end(),display<int>());  
  58.       
  59.       
  60.     cout<<endl;  
  61.     string stra1[]={"a","b","c"};  
  62.     string stra2[]={"d","e","f"};  
  63.       
  64.     cout<<lexicographical_compare(stra1,stra1+2,stra2,stra2+2)<<endl;//按照字典序 前者小于后者   
  65.     cout<<lexicographical_compare(stra1,stra1+2,stra2,stra2+2,greater<string>())<<endl;//按照字典序 前者不大于后者  
  66.       
  67.           
  68.     return 0;  

五,copy()对不同容器复制;关于输出区间与输入区间重叠的讨论
[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <deque>  
  4.   
  5. using namespace std;  
  6. template<class T>  
  7. struct display  
  8. {  
  9.     void operator()(const T &x)const  
  10.     {  
  11.         cout<<x<<" ";  
  12.     }  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     //以下复制区间没有问题   
  18.     int ia1[]={0,1,2,3,4,5,6,7,8};  
  19.     copy(ia1+2,ia1+7,ia1);//将下标2-6复制给 1-5  
  20.     for_each(ia1,ia1+9,display<int>()); //2,3,4,5,6,5,6,7,8  
  21.     cout<<endl;  
  22.        
  23.     //输出区间的起点与输入区间重叠,可能会有问题。但本例copy采用memmove()执行实际复制操作   
  24.     int ia2[]={0,1,2,3,4,5,6,7,8};  
  25.     copy(ia2+2,ia2+7,ia2+4);//将下标2-6复制给 4-8  
  26.     for_each(ia2,ia2+9,display<int>()); //0,1,2,3,2,3,4,5,6  
  27.     cout<<endl;  
  28.       
  29.     //以下复制区间没有问题   
  30.     int ia3[]={0,1,2,3,4,5,6,7,8};  
  31.     deque<int> id(ia3,ia3+9);  
  32.     deque<int>::iterator first=id.begin();  
  33.     deque<int>::iterator last=id.end();  
  34.     deque<int>::iterator result=id.begin();  
  35.     ++++first;  
  36.     cout<<*first<<endl;  
  37.     ----last;  
  38.     cout<<*last<<endl;  
  39.     cout<<*result<<endl;  
  40.     copy(first,last,result);  
  41.     for_each(id.begin(),id.end(),display<int>());//2,3,4,5,6,5,6,7,8  
  42.     cout<<endl;  
  43.       
  44.     //以下复制区间存在问题,由于实际复制没有采用memove(),结果错误   
  45.     int ia4[]={0,1,2,3,4,5,6,7,8};  
  46.     deque<int> ide(ia4,ia4+9);  
  47.     deque<int>::iterator first1=ide.begin();  
  48.     deque<int>::iterator last1=ide.end();  
  49.     deque<int>::iterator result1=ide.begin();  
  50.     advance(result1,4);//注意这里跟上面不一样   
  51.     ++++first1;  
  52.     cout<<*first1<<endl;  
  53.     ----last1;  
  54.     cout<<*last1<<endl;  
  55.     cout<<*result1<<endl;  
  56.     copy(first1,last1,result1);  
  57.     for_each(ide.begin(),ide.end(),display<int>());// 0,1,2,3,2,3,2,3,2不是预期的 0,1,2,3,2,3,4,5,6  
  58.     cout<<endl;  
  59.       
  60.       
  61.       
  62.     return 0;  
  63. }   

【注意】如果以vector 容器替代deque容器则每种情况都正确,因为vector迭代器其实是个源生指针,调用的copy()算法以mommove()执行实际复制。copy_backward(first,last,result);  //逆向复制,将迭代器first - last位置的元素逆向复制到 从result-1开始的逆向区间。

补充:

        原型:void *memmove( void  * dest, const   void  * src, size_t  count );

  用法:#include 或#include   功能:由src所指内存区域复制count个字节到dest所指内存区域。   说明:src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针。采取先拷贝再复制的方式,有效解决了dest和src区域重叠问题   相关函数:memset、memcpy、strcpy 参考博文http://blog.csdn.net/tianshuai11/article/details/7624419

实例

[html] view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. int main()  
  4. {  
  5.   char s[]="Golden Global View";  
  6.    memmove(s,s+7,strlen(s)+1-7);  
  7.    printf("%s",s);  
  8.       
  9.   return 0;  

六,Set方法

[html] view plain copy
  1. #include <iostream>  
  2. #include <set>  
  3. #include <algorithm>  
  4. #include <iterator>  
  5. using namespace std;  
  6.   
  7. template <class T>  
  8. struct display  
  9. {  
  10.     void operator()(const T &x)  
  11.     {  
  12.         cout<<x<<" ";  
  13.     }  
  14.       
  15. };  
  16. int main()  
  17. {  
  18.     int ia1[]={1,3,5,7,9,11};  
  19.     int ia2[]={1,1,2,3,5,8,13};  
  20.       
  21.     multiset<int> s1(ia1,ia1+6);  
  22.     multiset<int> s2(ia2,ia2+7);  
  23.     for_each(s1.begin(),s1.end(),display<int>());  
  24.     cout<<endl;  
  25.     for_each(s2.begin(),s2.end(),display<int>());  
  26.     cout<<endl;  
  27.       
  28.     multiset<int>::iterator first1 = s1.begin();  
  29.     multiset<int>::iterator last1 = s1.end();  
  30.     multiset<int>::iterator first2 = s2.begin();  
  31.     multiset<int>::iterator last2 = s2.end();  
  32.       
  33.     cout<<"union of s1 and s2: ";  
  34.     //两个集合合并,相同元素个数取 max(m,n)。   
  35.     set_union(first1,last1,first2,last2,ostream_iterator<int>(cout," "));  
  36.     cout<<endl;  
  37.       
  38.     first1=s1.begin();  
  39.     first2=s2.begin();  
  40.     cout<<"Intersection of s1 and s2: ";  
  41.     //两个集合交集,相同元素个数取 min(m,n).  
  42.     set_intersection(first1,last1,first2,last2,ostream_iterator<int>(cout," "));   
  43.     cout<<endl;  
  44.       
  45.     first1=s1.begin();  
  46.     first2=s2.begin();  
  47.     cout<<"Intersection of s1 and s2: ";  
  48.     //两个集合差集 就是去掉S1中 的s2   
  49.     set_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));   
  50.     cout<<endl;  
  51.        
  52.     first1=s1.begin();  
  53.     first2=s2.begin();  
  54.     cout<<"Intersection of s1 and s2: ";  
  55.     //两个集合对称差集:就是取两个集合互相没有的元素 。两个排序区间,元素相等指针后移,不等输出小的并前进   
  56.     //相同元素的个数 abs(m-n)   
  57.     set_symmetric_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));   
  58.     cout<<endl;  
  59.       
  60.       
  61.     return 0;  

 七,其他算法(运算逻辑相对单纯的算法)

[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <vector>  
  4. #include <functional>  
  5. #include <vector>   
  6.   
  7.   
  8. using namespace std;  
  9.   
  10. template <class T>  
  11. struct display  
  12. {  
  13.     void operator()(const T &x)const  
  14.     {  
  15.         cout<<x<<" ";   
  16.     }   
  17.       
  18. };   
  19.   
  20. struct even  
  21. {  
  22.     bool operator()(int x)const  
  23.     {  
  24.         return x%2?false:true;   
  25.     }   
  26. };  
  27.   
  28. class even_by_two  
  29. {  
  30. private:  
  31.     static int _x; //注意静态变量   
  32. public:  
  33.     int operator()()const  
  34.     {  
  35.         return _x+=2;   
  36.     }      
  37.       
  38. };  
  39. int even_by_two::_x=0;   
  40.   
  41. int main()  
  42. {  
  43.     int ia[]={0,1,2,3,4,5,6,6,6,7,8};  
  44.     vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));  
  45.       
  46.     //找出iv之中相邻元素值相等的第一个元素   
  47.     cout<<*adjacent_find(iv.begin(),iv.end())<<endl;    
  48.     cout<<*adjacent_find(iv.begin(),iv.end(),equal_to<int>())<<endl; //仿函数  
  49.       
  50.     cout<<count(iv.begin(),iv.end(),6)<<endl;//统计6的个数   
  51.     cout<<count_if(iv.begin(),iv.end(),bind2nd(less<int>(),7))<<endl;//统计小于7的元素的个数 :9个  
  52.       
  53.     cout<<*find(iv.begin(),iv.end(),4)<<endl; //返回元素为4的元素的下标位置  
  54.       
  55.     cout<<*find_if(iv.begin(),iv.end(),bind2nd(greater<int>(),2))<<endl; //返回大于2的第一个元素的位置:3  
  56.       
  57.     vector<int> iv2(ia+6,ia+8);//6 6  
  58.       
  59.     for(int i=0;i<iv2.size();++i)  
  60.       cout<<iv2[i]<<" ";   
  61.         
  62.     cout<<endl;   
  63.     //返回iv序列中 iv2序列 出现的最后一个位置(再往后三个位置的值):8   
  64.     cout<<"find_end:"<<*(find_end(iv.begin(),iv.end(),iv2.begin(),iv2.end())+3)<<endl;   
  65.      //返回iv序列中 iv2序列 出现的最后一个位置(再往后三个位置的值):7  
  66.     cout<<"find_first_of:"<<*(find_first_of(iv.begin(),iv.end(),iv2.begin(),iv2.end())+3)<<endl;  
  67.       
  68.        
  69.      for_each(iv.begin(),iv.end(),display<int>());   
  70.      cout<<endl;  
  71.        
  72.      //遍历整个iv2区间并执行 even_by_two操作   
  73.      generate(iv2.begin(),iv2.end(),even_by_two());  
  74.      for_each(iv2.begin(),iv2.end(),display<int>());   
  75.      cout<<endl;  
  76.        
  77.      //遍历区间(给出起点和长度),对每个遍历元素执行even_by_two操作   
  78.      generate_n(iv.begin(),3,even_by_two());  
  79.      for_each(iv.begin(),iv.end(),display<int>()); //由于_X是static 所以接着 增长   
  80.      cout<<endl;  
  81.        
  82.      //删除元素6 尾端可能有残余数据   
  83.      remove(iv.begin(),iv.end(),6);  
  84.      for_each(iv.begin(),iv.end(),display<int>()); //由于_X是static 所以接着 增长   
  85.      cout<<endl; //8 10 3 4 5 7 8 6 6 7 8 (最后四个是残留数据)   
  86.         
  87.      //去除value 然后将一个容器的元素复制到另一个 容器。仍然可能有残留元素   
  88.       vector<int> iv3(12);//重新申请空间  
  89.       remove_copy(iv.begin(),iv.end(),iv3.begin(),6);  
  90.       for_each(iv3.begin(),iv3.end(),display<int>()); //由于_X是static 所以接着 增长   
  91.       cout<<endl; //8 10 3 4 5 7 8 7 8 0 0 (最后两个是残留元素)   
  92.         
  93.       //将小于6的元素 "删除" iv 此时为 8 10 3 4 5 7 8 6 6 7 8   
  94.       remove_if(iv.begin(),iv.end(),bind2nd(less<int>,6));  
  95.       for_each(iv1.begin(),iv1.end(),display<int>()); //由于_X是static 所以接着 增长   
  96.       cout<<endl; //8 10 7 8 6 6 7 8 6 7 8 (最后三个是残留元素)   
  97.         
  98.         
  99.       //将小于7的元素 "删除"  iv3元素:8 10 3 4 5 7 8 7 8 0 0 (最后两个是残留元素)  
  100.       remove_copy_if(iv.begin(),iv.end(),iv3.begin(),bind2nd(less<int>,7));  
  101.       for_each(iv3.begin(),iv3.end(),display<int>()); //由于_X是static 所以接着 增长   
  102.       cout<<endl; //8 10 7 8 7 8 7 8 8 0 0(最后三个残留元素)   
  103.         
  104.         
  105.      return 0;   
  106. }  
第二段算法示例:
[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <vector>  
  4. #include <functional>  
  5.   
  6. using namespace std;  
  7.   
  8. template <class T>  
  9. struct display  
  10. {  
  11.     void operator()(const T &x)const  
  12.     {  
  13.         cout<<x<<" ";   
  14.     }   
  15.       
  16. };   
  17.   
  18.    
  19. int main()  
  20. {  
  21.     int ia[]={8,10,7,8,6,6,7,8,6,7,8};  
  22.     vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));  
  23.       
  24.     //将容器中6 替换为 3   
  25.     replace(iv.begin(),iv.end(),6,3);  
  26.     for_each(iv.begin(),iv.end(),display<int>()); //由于_X是static 所以接着 增长   
  27.     cout<<endl; //iv:8 10 7 8 3 3 7 8 3 7 8   
  28.       
  29.     vector<int> iv2(12);   
  30.     //将容器中3 替换为 5 放入另一个容器   
  31.     replace_copy(iv.begin(),iv.end(),iv2.begin(),3,5);  
  32.     for_each(iv2.begin(),iv2.end(),display<int>()); //由于_X是static 所以接着 增长   
  33.     cout<<endl; //iv2:8 10 7 8 5 5 7 8 5 7 8 0(最后y一个残留元素)   
  34.         
  35.     //将容器中小于 5 替换为 2   
  36.     replace_if(iv.begin(),iv.end(),bind2nd(less<int>(),5),2);  
  37.     for_each(iv.begin(),iv.end(),display<int>()); //由于_X是static 所以接着 增长   
  38.     cout<<endl; //iv:8 10 7 8 2 5 7 8 2 7 8   
  39.   
  40.     //将容器中小于 5 替换为 2   
  41.     replace_copy_if(iv.begin(),iv.end(),iv2.begin(),bind2nd(equal_to<int>(),8),9);  
  42.     for_each(iv2.begin(),iv2.end(),display<int>()); //由于_X是static 所以接着 增长   
  43.     cout<<endl; //iv2:9 10 7 8 2 5 7 9 2 7 8 0(最后一个残留元素)   
  44.       
  45.     //逆向重排每一个元素 (倒置)   
  46.     reverse(iv.begin(),iv.end());   
  47.     for_each(iv.begin(),iv.end(),display<int>());  
  48.     cout<<endl; //iv:8 7 2 8 7 5 2 8 7 10 8  
  49.       
  50.     //逆向重排每一个元素 (倒置)   
  51.     reverse_copy(iv.begin(),iv.end(),iv2.begin());   
  52.     for_each(iv2.begin(),iv2.end(),display<int>());  
  53.     cout<<endl; //iv2:8 10 7 8 2 5 7 8 2 7 8 0 (最后一个残留元素)    
  54.      
  55.     // 互换元素  [bigin,middle)  [middle,end)   
  56.     rotate(iv.begin(),iv.begin()+4,iv.end());  
  57.     for_each(iv.begin(),iv.end(),display<int>());  
  58.     cout<<endl;//iv:7 2 2 8 7 10 8 8 7 2 8   
  59.          
  60.     // 互换元素  [bigin,middle)  [middle,end)   
  61.     rotate_copy(iv.begin(),iv.begin()+5,iv.end(),iv2.begin());  
  62.     for_each(iv2.begin(),iv2.end(),display<int>());  
  63.     cout<<endl;//iv2:10 8 8 7 2 8 7 2 2 8 7 0 (最后一个是残留元素)   
  64.       
  65.       
  66.     //在iv中查找 子序列 2 8 第一次出现的位置的元素   
  67.     int ia2[3]={2,8};  
  68.     vector<int> iv3(ia2,ia2+2);  
  69.     cout<<*search(iv.begin(),iv.end(),iv3.begin(),iv3.end())<<endl; //2   
  70.       
  71.     //在iv中查找 2个8 出现的第一个位置的元素   
  72.     cout<<*search_n(iv.begin(),iv.end(),2,8)<<endl; //8   
  73.       
  74.     //在iv中查找 3个小于8 出现的第一个位置的元素   
  75.     cout<<*search_n(iv.begin(),iv.end(),3,8,less<int>())<<endl; //7  
  76.       
  77.     swap_ranges(iv3.begin(),iv3.end(),iv.begin());  
  78.     cout<<"iv:";   
  79.     for_each(iv.begin(),iv.end(),display<int>());//iv:2 8 2 8 7 10 8 8 7 2 8   
  80.     cout<<endl;  
  81.     cout<<"iv3:";   
  82.     for_each(iv3.begin(),iv3.end(),display<int>()); //iv3: 7 2   
  83.     cout<<endl;  
  84.         
  85.     //全部减2   
  86.     transform(iv.begin(),iv.end(),iv.begin(),bind2nd(minus<int>(),2));  
  87.     for_each(iv.begin(),iv.end(),display<int>());//0 6 0 6 5 8 6 6 5 0 6   
  88.     cout<<endl;   
  89.       
  90.      //两个区间元素相加然后放到 iv上   
  91.     transform(iv.begin(),iv.end(),iv.begin(),iv.begin(),plus<int>());  
  92.     for_each(iv.begin(),iv.end(),display<int>());  
  93.     cout<<endl; //0 12 0 12 10 16 12 12 10 0 12  
  94.       
  95.        
  96.      return 0;   
  97. }  
第三段算法示例:
[html] view plain copy
  1. #include <iostream>  
  2. #include <algorithm>  
  3. #include <vector>  
  4. #include <functional>  
  5.   
  6. using namespace std;  
  7.   
  8. template <class T>  
  9. struct display  
  10. {  
  11.     void operator()(const T &x)const  
  12.     {  
  13.         cout<<x<<" ";   
  14.     }   
  15.       
  16. };   
  17. struct even  
  18. {  
  19.     bool operator()(int x)const  
  20.     {  
  21.         return x%2?false:true;   
  22.     }   
  23. };  
  24.    
  25. int main()  
  26. {  
  27.     int ia[]={0,1,2,3,4,5,6,6,6,7,8};  
  28.     vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));  
  29.     vector<int> iv2(ia+4,ia+8);//4 5 6 6  
  30.     vector<int> iv3(15);  
  31.       
  32.     cout<<*max_element(iv.begin(),iv.end())<<endl;  
  33.     cout<<*min_element(iv.begin(),iv.end())<<endl;   
  34.   
  35.     //判断iv2中元素是否都出现在 iv中   
  36.     cout<<includes(iv.begin(),iv.end(),iv2.begin(),iv2.end())<<endl;   
  37.        
  38.     //iv 和iv2合并到iv3中   
  39.     merge(iv.begin(),iv.end(),iv2.begin(),iv2.end(),iv3.begin());   
  40.     for_each(iv3.begin(),iv3.end(),display<int>());  
  41.     cout<<endl;   
  42.       
  43.     //符合条件的 放到前面,不符合条件的放到后面   
  44.     partition(iv3.begin(),iv3.end(),even());  
  45.     for_each(iv3.begin(),iv3.end(),display<int>());  
  46.     cout<<endl;   
  47.       
  48.     //去除连续并且重复的元素   
  49.     unique(iv.begin(),iv.end());   
  50.     for_each(iv.begin(),iv.end(),display<int>());  
  51.     cout<<endl;   
  52.       
  53.       
  54.     //去除连续并且重复的元素   
  55.     unique_copy(iv.begin(),iv.end(),iv3.begin());   
  56.     for_each(iv3.begin(),iv3.end(),display<int>());  
  57.     cout<<endl;   
  58.       
  59.       
  60.      return 0;   
  61. }  

八,复杂算法示例(解释在源码中)

[html] view plain copy
  1. #include <iostream>  
  2. #include <vector>  
  3. #include <functional>  
  4. #include <algorithm>  
  5.   
  6. using namespace std;  
  7.   
  8. struct even //是否是奇数   
  9. {  
  10.     bool operator()(int x)const  
  11.     {  
  12.         return x%2?false:true;   
  13.     }   
  14.       
  15. };   
  16. template<class T>   
  17. struct display  
  18. {  
  19.     void operator()(T &x)const  
  20.     {  
  21.         cout<<x<<" ";   
  22.     }   
  23.       
  24. };   
  25.   
  26. int main()  
  27. {  
  28.     int ia[] = {12,17,20,22,23,30,33,40};  
  29.     vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));  
  30.       
  31.     //返回可以插入的第一个位置   
  32.     cout<<*lower_bound(iv.begin(),iv.end(),21)<<endl; //22   
  33.     cout<<*upper_bound(iv.begin(),iv.end(),21)<<endl; //22   
  34.     //返回可以插入的最后一个位置   
  35.     cout<<*lower_bound(iv.begin(),iv.end(),22)<<endl; //22   
  36.     cout<<*upper_bound(iv.begin(),iv.end(),22)<<endl; //23  
  37.       
  38.     //二分查找某个元素,返回是否找到   
  39.     cout<<binary_search(iv.begin(),iv.end(),33)<<endl; //1  
  40.     cout<<binary_search(iv.begin(),iv.end(),34)<<endl; //0   
  41.        
  42.     //生成下一个排列组合(字典序)   
  43.     next_permutation(iv.begin(),iv.end());   
  44.     for_each(iv.begin(),iv.end(),display<int>());  
  45.     cout<<endl;   
  46.        
  47.     prev_permutation(iv.begin(),iv.end());   
  48.     for_each(iv.begin(),iv.end(),display<int>());  
  49.     cout<<endl;   
  50.       
  51.     //打乱顺序   
  52.     random_shuffle(iv.begin(),iv.end());   
  53.     for_each(iv.begin(),iv.end(),display<int>());  
  54.     cout<<endl;  
  55.       
  56.     //找出最小的4个元素 放在前四个 后面顺序不一定有序   
  57.     partial_sort(iv.begin(),iv.begin()+4,iv.end());   
  58.     for_each(iv.begin(),iv.end(),display<int>());  
  59.     cout<<endl;  
  60.       
  61.     //排序(缺省为递增排序)   
  62.     sort(iv.begin(),iv.end());  
  63.     for_each(iv.begin(),iv.end(),display<int>());  
  64.     cout<<endl;  
  65.       
  66.      //排序(设置为递减)   
  67.     sort(iv.begin(),iv.end(),greater<int>());  
  68.     for_each(iv.begin(),iv.end(),display<int>());  
  69.     cout<<endl;  
  70.       
  71.     iv.push_back(22);  
  72.     iv.push_back(30);  
  73.     iv.push_back(17);  
  74.       
  75.       
  76.     //排序并保持原相对位置   
  77.     stable_sort(iv.begin(),iv.end());   
  78.     for_each(iv.begin(),iv.end(),display<int>());  
  79.     cout<<endl;//12 17 17 20 22 22 23 30 30 33 40   
  80.       
  81.     pair<vector<int>::iterator,vector<int>::iterator> pairIte;  
  82.     //返回等于22的一个小区间   
  83.     pairIte = equal_range(iv.begin(),iv.end(),22);   
  84.     cout<<*(pairIte.first)<<endl;//lowerbound 22   
  85.     cout<<*(pairIte.second)<<endl; //upperbound 23  
  86.       
  87.       
  88.     //这里返回一个空区间   
  89.     pairIte = equal_range(iv.begin(),iv.end(),25);   
  90.     cout<<*(pairIte.first)<<endl;//lowerbound 30   
  91.     cout<<*(pairIte.second)<<endl; //upperbound 30  
  92.        
  93.      //打乱顺序   
  94.     random_shuffle(iv.begin(),iv.end());   
  95.     for_each(iv.begin(),iv.end(),display<int>());  
  96.     cout<<endl;  
  97.       
  98.     //将小于iv.begin+5的放到左边   
  99.     nth_element(iv.begin(),iv.begin()+5,iv.end());   
  100.     for_each(iv.begin(),iv.end(),display<int>());  
  101.     cout<<endl;  
  102.       
  103.     //将小于iv.begin+5的放到右边   
  104.     nth_element(iv.begin(),iv.begin()+5,iv.end(),greater<int>());   
  105.     for_each(iv.begin(),iv.end(),display<int>());  
  106.     cout<<endl;  
  107.       
  108.     //排序   
  109.     stable_sort(iv.begin(),iv.end(),even());  
  110.     for_each(iv.begin(),iv.end(),display<int>());  
  111.     cout<<endl;  
  112.       
  113.       
  114.     return 0;   

二、string类

相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用。但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯定的。也许有人会说,即使不用MFC框架,也可以想办法使用MFC中的API,具体的操作方法在本文最后给出操作方法。其实,可能很多人很可能会忽略掉标准C++中string类的使用。标准C++中提供的string类得功能也是非常强大的,一般都能满足我们开发项目时使用。现将具体用法的一部分罗列如下,只起一个抛砖引玉的作用吧,好了,废话少说,直接进入正题吧!

要想使用标准C++中string类,必须要包含

#include // 注意是,不是,带.h的是C语言中的头文件

using  std::string;

using  std::wstring;

using namespace std;

下面你就可以使用string/wstring了,它们两分别对应着char和wchar_t。

string和wstring的用法是一样的,以下只用string作介绍:


string类的构造函数:

string(const char *s);    //用c字符串s初始化
string(int n,char c);     //用n个字符c初始化
此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常 ;


string类的字符操作:
const char &operator[](int n)const;
const char &at(int n)const;
char &operator[](int n);
char &at(int n);
operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
const char *data()const;//返回一个非null终止的c字符数组
const char *c_str()const;//返回一个以null终止的c字符串
int copy(char *s, int n, int pos = 0) const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目


string的特性描述:
int capacity()const;    //返回当前容量(即string中不必增加内存即可存放的元素个数)
int max_size()const;    //返回string对象中可存放的最大字符串的长度
int size()const;        //返回当前字符串的大小
int length()const;       //返回当前字符串的长度
bool empty()const;        //当前字符串是否为空
void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分

string类的输入输出操作:
string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。
函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。

string的赋值:
string &operator=(const string &s);//把字符串s赋给当前字符串
string &assign(const char *s);//用c类型字符串s赋值
string &assign(const char *s,int n);//用c字符串s开始的n个字符赋值
string &assign(const string &s);//把字符串s赋给当前字符串
string &assign(int n,char c);//用n个字符c赋值给当前字符串
string &assign(const string &s,int start,int n);//把字符串s中从start开始的n个字符赋给当前字符串
string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串

string的连接:
string &operator+=(const string &s);//把字符串s连接到当前字符串的结尾
string &append(const char *s);            //把c类型字符串s连接到当前字符串结尾
string &append(const char *s,int n);//把c类型字符串s的前n个字符连接到当前字符串结尾
string &append(const string &s);    //同operator+=()
string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾
string &append(int n,char c);        //在当前字符串结尾添加n个字符c
string &append(const_iterator first,const_iterator last);//把迭代器first和last之间的部分连接到当前字符串的结尾


string的比较:
bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等
运算符">","<",">=","<=","!="均被重载用于字符串的比较;
int compare(const string &s) const;//比较当前字符串和s的大小
int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中

                                  //pos2开始的n2个字符组成的字符串的大小
int compare(const char *s) const;
int compare(int pos, int n,const char *s) const;
int compare(int pos, int n,const char *s, int pos2) const;
compare函数在>时返回1,<时返回-1,==时返回0  


string的子串:
string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串

string的交换:
void swap(string &s2);    //交换当前字符串与s2的值


string类的查找函数:
int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
//查找成功时返回所在位置,失败返回string::npos的值
int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置
int rfind(const char *s, int pos = npos) const;
int rfind(const char *s, int pos, int n = npos) const;
int rfind(const string &s,int pos = npos) const;
//从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值
int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
int find_first_of(const char *s, int pos = 0) const;
int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;
//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos
int find_first_not_of(char c, int pos = 0) const;
int find_first_not_of(const char *s, int pos = 0) const;
int find_first_not_of(const char *s, int pos,int n) const;
int find_first_not_of(const string &s,int pos = 0) const;
//从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos
int find_last_of(char c, int pos = npos) const;
int find_last_of(const char *s, int pos = npos) const;
int find_last_of(const char *s, int pos, int n = npos) const;
int find_last_of(const string &s,int pos = npos) const;
int find_last_not_of(char c, int pos = npos) const;
int find_last_not_of(const char *s, int pos = npos) const;
int find_last_not_of(const char *s, int pos, int n) const;
int find_last_not_of(const string &s,int pos = npos) const;
//find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找


string类的替换函数:
string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符
string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符
string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c
string &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串s
string &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符
string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串s
string &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符c
string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串


string类的插入函数:
string &insert(int p0, const char *s);
string &insert(int p0, const char *s, int n);
string &insert(int p0,const string &s);
string &insert(int p0,const string &s, int pos, int n);
//前4个函数在p0位置插入字符串s中pos开始的前n个字符
string &insert(int p0, int n, char c);//此函数在p0处插入n个字符c
iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置
void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符
void insert(iterator it, int n, char c);//在it处插入n个字符c


string类的删除函数
iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串


string类的迭代器处理:
string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。
用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
const_iterator begin()const;
iterator begin();                //返回string的起始位置
const_iterator end()const;
iterator end();                    //返回string的最后一个字符后面的位置
const_iterator rbegin()const;
iterator rbegin();                //返回string的最后一个字符的位置
const_iterator rend()const;
iterator rend();                    //返回string第一个字符位置的前面
rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现


字符串流处理:
通过定义ostringstream和istringstream变量实现,#include 头文件中
例如:
    string input("hello,this is a test");
    istringstream is(input);
    string s1,s2,s3,s4;
    is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test"
    ostringstream os;
    os<     cout<

以上就是对C++ string类的一个简要介绍。用的好的话它所具有的功能不会比MFC中的CString类逊色多少,呵呵,个人意见!

最后要介绍如何在Win32 应用程序中引用MFC中的部分类,例如CString。

1.在工程目录下右键选择"Properties”--->"Configuration Properties”--->“General”--->"Use of MFC"--->"Use MFC in a Static Library",默认的是:"Use Standard Windows Libraries",如下图:

      

2.在你所用的所有头文件之前包含#include ,例如:可以在stdafx.h文件的最前面包含#include 头文件,这样在你的源代码中就可以使用CString类了,不过这样也有一个缺点,就是编译出来的程序要比原来的大很多。我试过一个小程序,选择"Use Standard Windows Libraries" 编译出来的Release版本大概92kb,使用"Use MFC in a Static Library"编译出来的Release版本大概192kb,足足大了100kb,这个就个人考虑了......

reference:

http://blog.csdn.net/tianshuai1111/article/details/7674327

http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html


你可能感兴趣的:(C/C++)