工欲善其事,必先利其器,你不得不知道的C++标准模板库,它从广义上讲分为algorithm(算法),container(容器),iterator(迭代器)三类,包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法
vector向量容器
使用前提: 加入头文件< vector >
常用方法:
- push_back 尾端插入新元素
- pop_back 删除尾端元素
- insert 向指定位置插入元素
- erase 删除指定位置的元素
- swap 交换值
- clear 清空全部元素
- empty 判断是否为空
- size 元素实际个数
方法演示:
#include <iostream>
using namespace std;
#include <vector> //引入头文件
int main(int argc, char** argv) {
vector<int> v;
puts("----- 尾端插入元素 -----");
v.push_back(1); //尾端插入新元素
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
puts("----- 迭代器遍历 -----");
vector<int>::iterator i;
int j;
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 删除末尾的最后一个元素 -----");
v.pop_back();
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 向指定位置插入元素 -----");
v.insert(v.begin()+2,6);//向第3个位置插入6
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
cout<<"-------------------------------------"<<endl;
v.insert(v.begin(),7);//向第1个位置插入7
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 删除指定位置元素 -----");
v.erase(v.begin()+1);//删除第2个元素
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 交换两个元素 -----");
swap(v[1],v[3]); //交换第2个元素和第4个元素
for(i=v.begin(),j=0;i!=v.end();i++,j++){
cout<<"v["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- for遍历 -----");
for(int i=0 ;i<v.size();i++){
cout<<v[i]<<" ";
}cout<<endl;
puts("----- 清空全部元素 -----");
v.clear();
puts("----- 元素实际个数 -----");
cout<<v.size()<<endl;
puts("----- 判断是否为空 -----");
cout<<v.empty()<<endl;
return 0;
}
演示结果:
deque 双端队列容器
deque与vector很相似,不仅可在尾部插入和删除数据,还可在头部插入和删除
使用前提: 加入头文件< deque >
常用方法:
- push_front 头部添加新元素
- pop_front 删除头部元素
- push_back 尾部添加新元素
- pop_back 删除尾部元素
- insert 向指定位置添加元素
- erase 删除指定位置的元素
- swap 交换两个元素的值
- clear 清空全部元素
- empty 判断是否为空
- size 实际大小
- front 首元素的值
- back 末元素的值
方法演示:
#include <iostream>
using namespace std;
#include <deque> //加入头文件
int main(int argc, char** argv) {
deque<string> d;
puts("----- 尾部添加元素 -----");
d.push_back("a");
d.push_back("b");
d.push_back("c");
puts("----- 迭代器遍历 -----");
int j;
deque<string>::iterator i;
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 头部添加元素 -----");
d.push_front("d");
d.push_front("e");
d.push_front("f");
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}
cout<<endl;
puts("----- 删除尾部元素 -----");
d.pop_back();
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}cout<<endl;
puts("----- 删除头部元素 -----");
d.pop_front();
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}cout<<endl;
puts("----- 指定位置的插入 -----");
d.insert(d.begin()+1,"l");//在第2个位置插入元素
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}cout<<endl;
puts("----- 指定位置的删除 -----");
d.erase(d.begin()+2);//删除第3个元素
for(i=d.begin(),j=0;i!=d.end();i++,j++){
cout<<"d["<<j<<"]="<<*i<<" ";
}cout<<endl;
puts("----- 实际个数 -----");
cout<<d.size()<<endl;
cout<<"d的首元素为"<<d.front()<<endl;
cout<<"d的末元素为"<<d.back()<<endl;
return 0;
}
演示结果:
list双向链表容器
使用前提: 加入头文件< list >
常用方法:
- push_back 尾端插入元素
- pop_back 删除尾端元素
- push_front 头部插入元素
- pop_front 删除头部元素
- insert ?
- erase ?
- remove 删除所有值为给定值的元素
- clear 删除所有元素
- sort 排序,默认为升序
- unique 除去连续的重复元素
问题:
注意! 这里的insert和erase方法会有问题,大家不妨试一下,你可以向vector和deque一样试着随机的插入数据,会报错的,显示没有对operator < 进行重载,所以,当你这样:v.insert(v.begin()+2,3),这样插入数据时,是会报错的!
问题剖析:
原因在于,底层采用链表实现的,说来也很奇怪,它却又重载了++。。。
真想插入元素,可以这样
puts("----- insert -----");
//往第三个位置插入999
for(i=v.begin(),j=0;i!=v.end()&&j<2;j++){
i++;
}
v.insert(i,999);
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
方法演示:
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <list>
int main(int argc, char** argv) {
list<int> v;
puts("----- 添加元素 -----");
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_front(4);
v.push_front(5);
v.push_front(6);
puts("----- 迭代器遍历 -----");
list<int>::iterator i;
int j;
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
puts("----- remove -----");
v.push_back(1);
v.push_back(1);
v.push_back(1);
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
v.remove(1);
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
puts("----- sort -----");
v.sort();
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
puts("----- unique -----");
v.push_front(7);
v.push_back(7);
v.push_back(7);
v.push_back(8);
v.push_back(7);
v.push_back(7);
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
v.unique();
for(j=0,i=v.begin();i!=v.end();i++,j++){
cout<<*i<<" ";
}
cout<<endl;
return 0;
}
演示结果:
set集合对象
**使用前提:**加入头文件< set >
常用方法:
- insert 插入元素
- erase 删除元素
- size 元素的数目
- empty 判断是否为空
- find 在当前集合中查找等于key值的元素,并返回指向该元素的迭代器;如果没有找到,返回指向集合最后一个元素的迭代器。
- count 返回某个值元素的个数,相当于判断该集合中是否存在该元素
- clear 删除所有元素
方法演示:
#include <iostream>
using namespace std;
#include <set>
int main(int argc, char** argv) {
set<int> s;
s.insert(3);
s.insert(4);
s.insert(5);
cout<<s.insert(5).second<<endl; //判断插入是否成功
set<int>::iterator i;
for(i=s.begin();i!=s.end();i++){
cout<<*i<<" ";
}
cout<<endl;
cout<<"元素的个数为"<<s.size()<<endl;
if(s.find(5)!=s.end()){
cout<<"找到了"<<endl;
cout<<*s.find(5)<<endl;
}else{
cout<<"未找到"<<endl;
}
cout<<"------------------------"<<endl;
cout<<s.count(8)<<endl;
return 0;
}
演示结果:
map映照对象:map映照容器的元素数据是一个键值和一个数据组成的,键值与映照数据之间具有一一映照的关系,采用红黑树来实现,插入键值得元素不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值索引检索出来
使用前提:加入头文件 < map >
演示:
#include <iostream>
using namespace std;
#include <map>
int main(int argc, char** argv) {
map<int,string> mapStudent;
mapStudent[1] = "student one";
mapStudent[1] = "student two";//id相同,则忽略
mapStudent[3] = "student three";
mapStudent[4] = "student four";
mapStudent[5] = "student five";
mapStudent[6] = "student six";
mapStudent[7] = "student seven";
mapStudent.insert(pair<int,string>(8,"student eight"));//插入
map<int,string>::iterator iter;
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<<iter->first<<":"<<iter->second<<endl;
//cout<<(*iter).first<<":"<<(*iter).second<<endl;
}
cout<<"-------------------"<<endl;
iter = mapStudent.find(1); //搜素
cout<<iter->first<<":"<<iter->second<<endl;
cout<<"-------------------"<<endl;
cout<< mapStudent.size()<<endl;
return 0;
}
演示结果
栈和队列
使用前提:加入头文件< stack > < queue >
演示:
#include <iostream>
using namespace std;
#include <stack>
#include <queue>
int main(int argc, char** argv) {
cout<<"----------Stack---------"<<endl;
stack<string> S;
S.push("123");//入栈
S.push("456");
S.push("789");
cout<<"栈的大小为"<<S.size()<<endl;
cout<<"栈是否为空"<<S.empty()<<endl;
cout<<S.top()<<endl;
S.pop();//出栈
cout<<S.top()<<endl;
S.pop();
cout<<S.top()<<endl;
S.pop();
// cout<<S.top()<<endl;
cout<<"----------Queue---------"<<endl;
queue<int> Q;
cout<<"队列是否为空"<<Q.empty()<<endl;
Q.push(1);//入队
Q.push(2);
Q.push(3);
cout<<Q.front()<<endl;//打印队首元素
cout<<Q.back()<<endl;//打印队尾元素
Q.pop();
cout<<Q.size()<<endl;//队列元素个数
cout<<Q.front()<<endl;//打印队首元素
cout<<Q.back()<<endl;//打印队尾元素
cout<<"队列是否为空"<<Q.empty()<<endl;
return 0;
}
演示结果:
优先队列容器 采用堆排序算法,每次将最大值或最小值出列
**使用前提:**加入头文件 < queue >
演示:
#include <iostream>
using namespace std;
#include <queue>
#include <vector>
class cmp{
public:
bool operator() (const int a,const int b)
{
return a>b;
}
};
int main(int argc, char** argv) {
// priority_queue<int> q;
priority_queue<int,vector<int>,cmp> q1;//默认为从大到小
priority_queue<int,vector<int> > q2;
int a[] = {93,5,2,33,52,13};
for(int i=0;i<6;i++){
q1.push(a[i]);
q2.push(a[i]);
}
while(!q1.empty()){
cout<<q1.top()<<" ";
q1.pop();//出队
}
cout<<endl;
while(!q2.empty()){
cout<<q2.top()<<" ";
q2.pop();//出队
}
cout<<endl;
return 0;
}
演示结果: