STL学习笔记

一、SET容器

set:插入后自动按从小到大的顺序排列,如果是结构体的话需要重载<,集合内元素不允许重复。

 

set的一些操作见代码:

#include <iostream>
#include <set>

using namespace std;

typedef struct tagStudentInfo
{
  int nID;
  string strName;
  bool operator <(tagStudentInfo const& _A) const//升序排列

    {
     if(nID<_A.nID) 
     return true;
     if(nID == _A.nID)
     return strName.compare(_A.strName) < 0;
        return false;
    }
}sInfo,*PsInfo;

int main()
{
  set<sInfo>setS;
  sInfo stuInfo;

  stuInfo.nID = 10;
  stuInfo.strName = "test1";
  setS.insert(stuInfo);
  
  stuInfo.nID = 20;
  stuInfo.strName = "test2";
  setS.insert(stuInfo);

  set<sInfo>::iterator sIter;
  for(sIter=setS.begin(); sIter!=setS.end(); sIter++)
  {
    cout <<(*sIter).nID <<" "<< (*sIter).strName << endl;
  }

  set<int>a;
  set<int>b;
  set<int>c;
  set<int>d;
  set<int>e;
   
  a.insert(1);
  a.insert(2);
  a.insert(3);
  a.insert(4);
  a.insert(5);

  b.insert(3);
  b.insert(4);
  b.insert(5);
  
  set_union(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.begin()));
  set<int>::iterator s;
  for(s=c.begin(); s!=c.end(); s++)
  {
    cout <<(*s)<<",";
  }
  cout << endl;
  
  set_intersection(a.begin(), a.end(), b.begin(), b.end(), inserter(d, d.begin()));
  for(s=d.begin(); s!=d.end(); s++)
  {
    cout <<(*s) <<",";
  }
  cout << endl;
  
  set_difference(a.begin(), a.end(), b.begin(), b.end(), inserter(e, e.begin()));
  for(s=e.begin(); s!=e.end(); s++)
  {
    cout <<(*s)<<",";
  }
  cout <<endl;
  
  return 0;
}    

 二、MAP容器

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

插入数据可以通过 inser(pair<typenameA,typenameB>(A,B))、insert(map<typenameA,typenameB>::value_type(A,B))或数组形式(一般不用)。

 1 #include <map>  
 2 #include <string> 
 3 #include <iostream> 
 4 using namespace std; 
 5 int main() 
 6 { 
 7     map<int, string> mapStudent; 
 8     mapStudent.insert(pair<int, string>(1, "student_one")); 
 9     mapStudent.insert(pair<int, string>(2, "student_two")); 
10     mapStudent.insert(pair<int, string>(3, "student_three")); 
11     map<int, string>::iterator  iter; 
12     for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++) 
13     { 
14     cout<<iter->first<<"    "<<iter->second<<endl; 
15     } 
16     system("pause");
17 } 
View Code

 

mapStudent.insert(map<int, string>::value_type (1, “student_one”));
mapStudent.insert(map<int, string>::value_type (1, “student_two”)); 

 

上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下 

Pair<map<int, string>::iterator, bool> Insert_Pair; 
Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, “student_one”)); 

数据的遍历:

前向iterator已经实现过了,反向iterator为:

for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++) 
{ 
    Cout<<iter->first<<”   ”<<iter->second<<end; 
} 

数据的查找:

find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器,程序说明 \

#include <map> 
#include <string> 
#include <iostream> 
using namespace std; 
int main() 
{ 
    map<int, string> mapStudent; 
    mapStudent.insert(pair<int, string>(1, "student_one")); 
    mapStudent.insert(pair<int, string>(2, "student_two")); 
    mapStudent.insert(pair<int, string>(3, "student_three")); 
    map<int, string>::iterator iter; 
    iter = mapStudent.find(1); 
    if(iter != mapStudent.end()) 
    { 
        cout<<”Find, the value is ”<<iter->second<<endl; 
    } 
    else 
    { 
        cout<<”Do not Find”<<endl; 
    } 
} 

 清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map。

mapStudent.insert(pair<int, string>(1, “student_one”)); 
mapStudent.insert(pair<int, string>(2, “student_two”)); 
mapStudent.insert(pair<int, string>(3, “student_three”)); 

//如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好 
//如果要删除1,用迭代器删除 
map<int, string>::iterator iter; 
iter = mapStudent.find(1); 
mapStudent.erase(iter); 

//如果要删除1,用关键字删除 
Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0 

//用迭代器,成片的删除 
//一下代码把整个map清空 
mapStudent.earse(mapStudent.begin(), mapStudent.end()); 
//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合 

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题 
第一种:小于号重载,程序举例 

对于没有默认排序的结构体,如果使用map容器,程序是无法编译通过的,只要重载小于号,就OK了,如下: 

typedef struct tagStudentInfo 
{ 
int      nID; 
string   strName; 
bool operator < (tagStudentInfo const& _A) const 
{ 
  //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序 
  if(nID < _A.nID)  return true; 
  if(nID == _A.nID) return strName.compare(_A.strName) < 0; 
     return false; 
} 
}studentInfo, *PStudentInfo;  //学生信息 

 


第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明 

#include <map> 
#include <string> 
using namespace std; 
typedef struct tagStudentInfo 
{ 
    int      nID; 
    string   strName; 
}StudentInfo, *PStudentInfo;  //学生信息 

Classs sort 
{ 
Public: 
    bool operator() (StudentInfo const &_A, StudentInfo const &_B) const 
    { 
      if(_A.nID < _B.nID) return true; 
      if(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0; 
      return false; 
    } 
}; 

int main() 
{ 
    //用学生信息映射分数 
    map<StudentInfo, int, sort>mapStudent; 
    studentInfo studentInfo; 
    studentInfo.nID = 1; 
    studentInfo.strName = "student_one"; 
    mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90)); 
    studentInfo.nID = 2; 
    studentInfo.strName = "student_two"; 
    mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80)); 
} 

 

  二、STACK容器

 STACK容器遵循后进先出(LIF0)

push() 往堆栈顶端加入元素, top() 获取顶端元素 , pop()弹出顶端元素,很简单的STL,类似于vector容器。

posted @ 2014-12-08 22:59  wcm_94  阅读(174)  评论(0编辑  收藏  举报