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 }
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容器。