快考CSP了,C/C++玩家的福利来了
首先介绍下,什么是STL。STL,Standard Template Library的缩写,标准模版库的意思。STL是一些“容器”的集合,这些容器包括list、 vector、set、queue等。
PS:这里说明下,文中出现的DataType指数据类型,DataName指变量名,cmp指一个返回类型为bool的比较函数
要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
迭代器按照定义方式分成以下四种。
正向迭代器,定义方法如下:
容器类名::iterator 迭代器名;
常量正向迭代器,定义方法如下:
容器类名::const_iterator 迭代器名;
反向迭代器,定义方法如下:
容器类名::reverse_iterator 迭代器名;
常量反向迭代器,定义方法如下:
容器类名::const_reverse_iterator 迭代器名;
迭代器用法示例会在后边不同容器示例中展示。
所谓动态数组,就是不定长数组。
头文件:#include
声明:vector
基本操作:
push_back();
,在最后面插入一个新元素size()
,返回vector的长度clear()
,清空vector例子:
vector<int> vec; //空的
vec.push_back(0); //有0
vec.push_back(1); //有0,1
vec.push_back(2); //有0,1,2
//两种遍历方法
for(int i=0; i<vec.size(); i++){
printf("%d\n",vec[i]);
}
for(vector<int>::iterator it=vec.begin(); it!=vec.end(); it++){
printf("%d\n",*it);//迭代器访问
}
vec[1]=3; //变成0,3,3
vec[2]=2; //变成0,3,2
vec.clear();//清空
先进后出的数据结构(FILO)
头文件:#include
声明:stack
基本操作:
push()
,入栈pop()
,出栈top()
,访问栈顶元素empty()
,判断栈空size()
,返回栈中元素个数例子:
s.push(1); //{1}
s.push(233); //{233,1}
s.push(666); //{666,233,1}
cout<<s.top()<<endl; //输出栈顶666
cout<<s.size()<<endl; //输出栈中元素个数3
s.pop(); //{233,1}
s.push(2); //{2,233,1}
先进先出的数据结构(FIFO)
头文件:#include
声明:queue
基本操作:
push()
,入队pop()
,出队front()
,访问队首元素back()
,访问队尾元素empty()
,判断队空size()
,返回队列元素个数例子:
int e,m,n;
queue<int> q1;
for(int i=0;i<10;i++)
q.push(i); //入队
//[0,1,2,3,4,5,6,7,8,9]
if(!q1.empty())
cout<<"no empty\n";
n=q1.size(); //n=10
m=q1.back(); //m=9
for(int i=0;i<n;i++){
e=q1.front(); //取队首元素
cout<<e<<" ";
q1.pop(); //出队
}
cout<<endl;
if(q1.empty())
cout<<"queue is empty";
集合中不会存在重复元素,支持高效的插入、删除和查询操作,复杂度均是O(logn)(对比使用数组来实现,虽然插入的时间复杂度O(1),但是删除和查询的时间复杂度却是O(n))。
头文件:#include
声明:set
基本操作:
begin()
,返回set第一个元素(类型为迭代器,或者说指针)end()
,返回set最后一个元素(同上)clear()
,清空set中的元素empty()
,判断set是否为空insert()
,插入一个元素erase()
,删除一个元素find()
,查找一个元素,返回为迭代器size()
,返回set的元素个数例子:
set<int> s;
set<int>::iterator it;
s.insert(1); //{1}
s.insert(2); //{1,2}
s.insert(3); //{1,2,3}
s.insert(1); //{1,2,3}
s.erase(1); //{2,3}
it=s.find(2); //查找元素2,若未找到,返回s.end()
从一个元素映射到另一个元素的数据结构,hash是他的一种。
头文件:#include
声明:map
从DataTypeA映射到DataTypeB
基本操作:
count()
,判断是否存在映射clear()
,清空map例子:
map<string,int> dict; //{}
dict["Tom"]=1; //{"Tom":1}
dict["Jone"]=2; //{"Tom":1,"Jone":2}
dict.insert(map<string,int>::value_type("Mary",1));
// //{"Tom":1,"Jone":2,"Mary":1}
if(dict.count("Mary")){
printf("Mary存在");
} else{
printf("Mary不存在");
}
//迭代器访问
for(map<string,int>::iterator it=dict.begin(); it!=dict.end(); it++){
cout<<it->first<<":"<<it->second<<endl;
}
实质就是二叉堆,使用该模版可以快速实现小根堆、大根堆。插入、删除、查询的时间复杂度均是O(logn)。
头文件:#include
声明: 默认小根堆,priority_queue
自定义比较函数,priority_queue
基本操作:
push()
,队尾插入元素pop()
,取出队首元素top()
,访问队首元素size()
,获取队列长度clear()
,清空队列例子:
struct cmp{
bool operator() (const int &a,const int &b){//&引用
return a>b; //最大堆
}
};
priority_queue<int,vector<int>,cmp> q;//[]
q.push(2); //[2]
q.push(1); //[2,1]
q.push(3); //[3,2,1]
for(int i=0;i<q.size();i++){
printf("%d\n",q.top());//逐个输出队首
q.pop();//出队
}
头文件:#include
sort(begin,end,cmp);
//begin为序列开始地址,end序列结束地址,cmp比较函数,cmp可以不填,默认升序
数组排序:
int a[4]={2,4,3,1};
int n=4;
sort(a,a+n);
vector排序:
sort(vec.begin(),vec.end());
结构体排序:
struct Point{
int x,y;
}p[4]={{1,2},{1,0},{2,1},{0,1}};
bool cmp(Point a,Point b){
//比较函数,x为主关键字升序,y为次关键字升序
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
int main(){
sort(p,p+4,cmp);
return 0;
}