今天学习了C++STL泛型编程的基础知识,我对主要知识整理如下:
STL提供三种类型的组件:容器,迭代器,算法。支持泛型程序设计标准。
容器主要有两类:顺序容器和关联容器。
顺序容器:vector,list,deque,string等都是一系列连续元素的集合。
关联容器:set,multiset,map,multimap包含查找元素的键值。
迭代器:遍历容器
STL算法库:排序算法,不可变序算法,变序性算法,数值算法。
/*******************************************************************************************************/
Vector容器简介
(1)优势:可以随机访问各个元素还可以在尾部添加元素。因此可以完全代替数组。具有内存自动管理功能,可以随时动态调整内存功能。
(2)基本内容
头文件声明:#include<vector>
vector容器是从下标0开始计数,我们可以事先固定一个大小,事后可以随时调整其大小;也可事先不定义,随时使用push_back()方法从尾部扩张,也可以使用insert()方法在某个元素位置前插入元素。
vector容器的两个重要方法:
begin()和end():begin()方法返回首元素位置的迭代器,end()方法返回最后一个元素的下一个元素的位置的迭代器。
(3)创建对象
 法1:vector<int>v;
 法2:vector<double>v(10);(固定大小)
 法3:vector<double>v(10,8.6);(固定了大小并且初始化)
(3)元素的尾部扩张
#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int>v;
    v.push_back(2);
    v.push_back(7);
    v.push_back(9);
    return 0;
}
(4)下标访问vector元素
#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int>v(3);
    v[0]=2;
    v[1]=7;
    v[2]=9;
    cout<<v[0]<<v[1]<<v[2]<<endl;
    return 0;
}
(5)使用迭代器访问vector元素
迭代器的类型必须与遍历的vector对象的元素的类型一致
#include<iostream>
#include<vector>
using namespace std;
int main()
{
   vector<int>v;
   v.push_back(3);
   v.push_back(6);
   v.push_back(9);
   vector<int>::iterator it;
   for(it=v.begin();it!=v.end();it++)
   {
      cout<<*it<<endl;
   }
   return 0;
}
(6)元素的插入
insert()方法可以在vector对象的任意位置之前插入一个新的元素,同时vector自动扩张一个元素的空间,插入位置后所有元素依次向后挪动一个位置。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int>v(3);
    v[0]=1;
    v[1]=3;
    v[2]=6;
    v.insert(v.begin(),8);
    v.insert(v.begin()+2;9);//在第二个元素前插入元素9
    for(it=v.begin();it!=v.end();it++)
    {
      cout<<*it<<endl;
    }
    return 0;
}
(7)元素的删除
erase()方法可以删除vector中迭代器所指的一个元素或者一段区间的所有元素。clear()方法可以删除所有元素。
#include<iostream>
#include<vector>
using namespace std;
int main()
{   
    vector<int>v(3);
    v[0]=1;
    v[1]=3;
    v[2]=6;
    v.erase(v.begin()+2);//删除第二个元素
    v.erase(v.begin(),v.end());//删除所有元素
    return 0;
}
(8)元素的反转
reverse()方法:头文件是#include<algorithm>
reverse(v.begin(),v.end());
(9)元素排序
sort()方法:头文件#include<algorithm>
默认方法是升序
可以自定义排序方法:
bool  cmp(const int &a,const int &b)
{
   return a>b;
}
sort(v.begin(),v.end(),cmp);
(10)向量的大小
size()方法和empty()方法
v.size()和v.empty()。
/************************************************************************************************/
string 容器简介:
(1)创建string对象
    string s;//初试长度为0
(2)给string对象赋值
   法1:s="sjdjfj‘;
   法2:char ss[20];
        scanf("%s",ss);
        s=ss;
(3)string对象尾部添加字符
   s=s+‘a‘;
(4)string对象尾部添加字符串
   法1:s=s+"abc";
   法2:s.append("abc");
(5)string对象插入字符
   string::iterator it=s.begin();
   s.insert(it+1,‘a‘);
(6)访问string对象元素
   s="acffggg";
   cout<<s[0];
(7)删除string对象的元素
   1.清空字符串可以直接赋值空字符串即可;
   2.使用erase()方法删除迭代器所指的那个元素或者那个区间所有元素;
    string s="aaaaffggg";
    string::iterator it=s.begin();
    s.erase(it+1);
    s.erase(it+1,it+4);
(8)返回string对象的长度以及判断是否为空
    s.length()及s.empty();
(9)替换string中的字符
   s.replace(3,3,"gppg");//从第三个字符开始将连续的3个字符替换为"gppg"
(10)搜索string对象的元素或者子串
   采用find()方法:查找一个字符用单引号‘’界定;查找一个字符串用双引号""界定。
   s.find(‘c‘);
   s.find("sdd");
(11)string对象的比较
   string对象可以用compare()方法与其它字符串进行比较,如果它比对方大,则返回1;如果它比对方小,则返回-1;
   如果它与对方相同,则返回0.
   s.compare("ssfgg");
(12)反向排序string对象
   reverse()方法:头文件#include<algorithm>
   reverse(s.begin(),s.end());
(13)string对象作为 vector元素
   vector<string>v;
   v.push_back("jack");
   v.push_back("shfj");
   cout<<v[0]<<v[1]<<endl;
   cout<<v[0][0]<<endl;
   cout<<v[0].length()<<endl;
(14)string对象与字符数组互操作
   char  ss[100];
   scanf("%s",ss);
   s=ss;
   printf(s.c_str());
   cout<<endl;
   printf("%s",ss);
(15)string对象与sscanf函数
   string s1,s2,s3;
   char sa[100],sb[100],sc[100];
   sscanf("abc 123 pc","%s %s %s",sa,sb,sc);
   s1=sa;
   s2=sb;
   s3=sc;
   cout<<s1<<‘ ‘<<s2<<‘ ‘<<s3<<endl;
   int a,b,c;
   sscanf("1 2 3","%d %d %d",&a,&b,&c);
   cout<<a<<‘ ‘<<b<<‘ ‘<<c<<endl;
   int x,y,z;
   sscanf("4,5$6","%d,%d$%d",&x,&y,&z);
   cout<<x<<‘ ‘<<y<<‘ ‘<<z<<endl;
(16)string对象与数值相互转换
   #include<iostream>
   #include<vector>
   #include<sstream>
   #include<string>
   using namespace std;
   
   string  convertToString(double x)
   {
      ostringstream o;
      if(o<<x)  return o.str();//将变量x读取到字符流o中
      return "error";
   }
    double convertFromString(const string &s)
   {
      istringstream i(s);
      double x;
      if(i>>x) return x;//相当于把字符串从字符流中读取到变量x中
      return  0.0;
   }
    int main()
   {
      char b[10];
      string a;
      sprintf(b,"%d",1975);
      a=b;
      cout<<a<<endl;
      string cc=convertToString(1976);
      cout<<cc<<endl;
      string dd="2006";
      int p=convertFromString(dd)+2;
      cout<<p<<endl;
      return 0;
   }
/***************************************************************************************************/ 
set集合容器(红黑树原理)
(1)创建set集合对象
     set<int>s;
(2)元素的插入和中序遍历,反向遍历(使用前向迭代器)
   #include<set>
   #include<iostream>
   using namespace std;
   int main()
   {
       set<int>s;
       s.insert(8);
       s.insert(1);
       s.insert(12);
       s.insert(6);
       s.insert(8);//重复,不执行插入操作
       set<int>::iterator it;
       for(it=s.begin();it!=s.end();it++)//正向遍历
       cout<<*it<<endl;
       set<int>::reverse_iterator rit;//反向遍历
       for(rit=s.rbegin();rit!=s.rend();rit++)
       {
           cout<<*rit<<endl;
       }
       return  0;
   }
(3)元素的删除
   #include<set>
   #include<iostream>
   using namespace std;
   int main()
   {
       set<int>s;
       s.insert(8);
       s.insert(1);
       s.insert(12);
       s.insert(6);
       s.insert(8);//重复,不执行插入操作
       s.erase(6);//删除元素6(键值)
       set<int>::reverse_iteerator rit;
       for(rit=s.rbegin();rit!=s.rend();rit++)
       cout<<*rit<<endl;
       cout<<s.size()<<endl;
       return 0;
   }
(4)元素的检索
   使用find()方法进行搜索,查到以后返回该键值在迭代器中的位置,否则返回最后一个元素后面的一个位置,即end()。
   set<int>::iterator it;
   it=s.find(6);
   if(it!=s.end()) cout<<*it<<endl;
(5)自定义比较函数
   案例1:
   #include<set>
   #include<iostream>
   using namespace std;
   struct mycomp
   {
      bool operator()(const int &a,const int &b)
      {
        return a>b;
      }
   };
   int main()
   {
     set<int,mycomp>s;
     s.insert(3);
     s.insert(7);
     s.insert(11);
     s.insert(12);
     set<int,mycomp>::iterator it;
     for(it=s.begin();it!=s.end();it++)
     {
       cout<<*it<<endl;
     }
     return 0;
   }
   案例2:
   #include<set>
   #include<iostream>
   using namespace std;
   struct info
   {
     string name;
     float  score;
     bool operator<(const info &a)const
     {
         return  a.score<score;
     }
   };
   int main()
   {
      set<info>s;
      info ifo;
      ifo.name="dd";
      ifo.score=999;
      s.insert(ifo);
      ifo.name="ss";
      ifo.score=799;
      s.insert(ifo);
      set<info>::iterator it;
      for(it=s.begin();it!=s.end();it++)
      cout<<*it<<endl;
      return  0;
   }
multiset多重集合容器(可重复元素的红黑树原理)
(1)multiset元素的插入(头文件依然是#include<set>)
   #include<set>
   #include<string>
   #include<iostream>
   using namespace std;
   int main()
   {
      multiset<string>s;
      s.insert("aad");
      s.insert("bbc");
      multiset<string>::iterator it;
      for(it=s.begin();it!=s.end();it++)
      cout<<*it<<endl;
      return 0;
   }
(2)multiset元素的删除
采用erase()方法可以删除multiset对象中的某个迭代器位置上的元素,某段迭代器区间中的元素,键值等于某个值的所有重复元素,并返回删除元素的个数。采用clear()方法可以清空元素。
#include<set>
#include<string>
#include<iostream>
using namespace std;
int main()
{
   multiset<string>s;
   s.insert("ssjj");
   s.insert("ssjj");
   s.insert("dggh");
   multiset<string>::iterator it;
   int n=s.erase("ssjj");
   for( it=s.begin();it!=s.end();it++)
   cout<<*it<<endl;
   return 0;
}
(3)查找元素
find方法查找元素如果找到,返回该元素的迭代器位置(如果元素重复,返回第一个重复元素的迭代器位置);如果没有找到,则返回end()迭代器位置。
#include<set>
#include<string>
#include<iostream>
using namespace std;
int main()
{
   multiset<string>s;
   s.insert("abc");
   s.insert("def");
   s.insert("hgjj");
   multiset<string>::iterator it;
   it=ms.find("abc");
   if(it!=s.end())
   cout<<*it<<endl;
   return 0;
}
/******************************************************************************************/
map容器简介
map容器的数据结构采取的是红黑树来实现的,插入元素的键值不允许改变,比较函数只对元素的键值进行比较。
(1)创建map对象
键值与映照数据的类型自己定义。
#include<map>
#include<iostream>
#include<string>
using namespace std;
int main()
{
   map<string,float>m;
   m["jack"]=98.5;
   m["bomi"]=96;
   m["kagr"]=67;
   map<string,float>::iterator it;
   for(it=m.begin();it!=m.end();it++)
   cout<<(*it).first<<‘ ‘<<(*it).second<<endl;
   return 0;
}
(2)删除元素
采用erase()函数可以删除一个元素,一段元素,键值重复的元素。
#include<iostream>
#include<string>
#include<map>
int main()
{
    map<int,char>s;
    s[1]=‘a‘;
    s[20]=‘t‘;
    s[15]=‘v‘;
    s.erase(20);
    map<int,char>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    cout<<(*it).second<<endl;
    return 0;
}
(3)元素的反向遍历
使用迭代器reverse_iterator反向遍历和rbegin(),rend()方法进行遍历。
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
    map<int,char>s;
    s[1]=‘a‘;
    s[2]=‘b‘;
    s[20]=‘f‘;
    map<int,char>::reverse_iterator rit;
    for(rit=s.rbegin();rit!=s.rend();rit++)
    cout<<(*rit).first<<‘ ‘<<(*rit).second<<endl;
    return 0;
}
(4)元素的搜索
使用find()方法搜索某个键值,搜索到以后返回所在的迭代器位置,否则返回end()迭代器位置。
法1:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
    map<int,char>s;
    s[1]=‘a‘;
    s[2]=‘b‘;
    s[20]=‘f‘;
    map<int,char>::iterator it;
    it=s.find(2);
    if(it!=s.end())
    cout<<(*it).first<<‘ ‘<<(*it).second<<endl;
    return 0;
}
(5)自定义比较函数
默认函数排序是按照键值从小到大的顺序插入元素
#include<iostream>
#include<string>
#include<map>
using namespace std;
struct mycomp
{
   bool operator()(const int &a,const int &b)
   {
     return a>b;
   }
};
int main()
{
   map<int,char,mycomp>m;
   m[25]=‘m‘;
   m[28]=‘f‘;
   m[10]=‘a‘;
   map<int,char,mycomp>::iterator it;
   for(it=m.begin();it!=m.end();it++)
   {
      cout<<(*it).first<<‘ ‘<<(*it).second<<endl;
   }
   return 0;
}
法2:
#include<iostream>
#include<string>
#include<map>
using namespace std;
struct info
{
    string name;
    float score;
    bool operator<(const info &a)const
    {
       return a.score<score;
    }
}; 
int main()
{
  map<info,int>m;
  info ifo;
  ifo.name="sdj";
  ifo.score=80;
  m[ifo]=25;
  map<info,int>::iterator  it;
  for(it=m.begin();it!=m.end();it++)
  {
     cout<<(*it).second;
     cout<<((*it).first).name<<‘ ‘<<((*it).first).score<<endl;
  }
  return 0;
}
Application:
1.map容器实现数字分离
#include<string>
#include<map>
#include<iostream>
int main()
{
   map<char,int>m;
   for(int i=0;i<10;i++)
   {
     m[‘0‘+j]=j;
   }
   string sa;
   sa="asddddd";
   int sum=0;
   for(int i=0;i<sa.length();i++)
   sum+=m[sa[i]];
   cout<<sum<<endl;
   return 0;
}
2.map容器实现数字印照字符
#include<iostream>
#include<map>
#include<string>
int main()
{
   map<int,char>m;
   for(int i=0;i<10;i++)
   m[j]=‘0‘+j;
   string a="the number is:";
   cout<<s+m[7]<<endl;
   return 0;
}
/******************************************************************************************************/
multimap容器简介
(1)元素的插入
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
   mmultimap<string,double>m;
   m.insert(pair<string,double>("jack",300.5));
   m.insert(pair<string,double>("lan",5868));
   m.insert(pair<string,double>("hdhf",6886));
   multimap<string,double>::iterator  it;
   for(it=m.begin();it!=m.end();it++)
   cout<<(*it).first<<‘ ‘<<(*it).second<<endl;
   return 0;
}
(2)元素的删除
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
   multimap<string,double>m;
   m.insert(pair<string,double>("jack",300.6));
   m.insert(pair<string,double>("jsjjd",300.56));
   m.insert(pair<string,double>("djj",384));
   m.erase("jack");
   multimap<string,double>::iterator it;
   for(it=m.begin();it!=m.end();it++)
   cout<<(*it).first<<‘ ‘<<(*it).second<<endl;
   return 0;
}
(3)元素的查找
采用find()方法,如果找到则返回第一个键值的下标,否则返回end()迭代器位置。
/******************************************************************************************/
list双向链表容器
list每个节点有三个域:前驱元素指针域,数据域,后继元素指针域
对于迭代器只能通过“++”或者“--”的操作将迭代器移动到后继/前驱节点上,不能执行操作"+n"或者"-n";
(1)创建list对象
1.创建空链表:list<int>m;
2.创建具有n个元素的链表:list<int>m(10);
(2)元素的插入与遍历
采用push_back(),push_front(),insert()方法进行。
#include<list>
#include<iostream>
using namespace std;
int main()
{
   list<int>m;
   m.push_back(2);
   m.push_back(6);
   m.push_front(9);
   list<int>::iterator it;
   it++;
   m.insert(it,20);
   for(it=m.begin();it!=m.end();it++)
   cout<<(*it)<<endl;
   return  0;
}
(3)反向遍历
采用反向迭代器reverse_iterator加rbegin(),rend()方法进行反向遍历
(4)元素删除
1.使用remove()方法删除链表中一个元素值相同的元素都会被删除;
2.使用pop_front()和pop_back()方法进行删除首尾元素;
3.使用erase()方法删除迭代器位置上的元素;
   list<int>::iterator it;
   it=s.begin();
   it++;
   s.erase(it);
4.使用clear()方法清空list
(4)元素查找
使用find()方法查找:
list<int>::iterator it;
it=find(l.begin(),l.end(),7);
if(it!=l.end())
cout<<*it<<endl;
(5)元素排序
使用sort()方法
(6)剔除连续重复元素
使用unique()方法
/**************************************************************************************/
priority_queue优先队列容器
push():插入元素
pop():删除元素
top():读取队首元素
empty():是否为空
size():读取元素数量
重载<操作符定义优先级
struct info
{
  string name;
  float score;
  bool  operator<(const Info &a)const
  {
    return a.score<score;
  }
};
priority_queue<info>q;
重载“()”操作符定义优先级
struct mycomp
{
   bool operator()(const int &a,int &b)
   {
     return a>b;//这里与其它容器相反,>表示从小到大排列,<表示从大到小排列
   }
};
C++STL泛型编程基础知识讲解--------2015年2月3日
原文:http://www.cnblogs.com/khbcsu/p/4271332.html