STL
-
算法 头文件:<algorithm>,<numeric>和<functional>
-
容器 头文件:<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>
下面详细介绍各种容器:
C++中有两种类型的容器:顺序容器和关联容器。顺序容器主要有vector、list、deque等。其中vector表示一段连续的内存,基于数组实现,list表示非连续的内存,基于链表实现,deque与vector类似,但是对首元素提供插入和删除的双向支持。关联容器主要有map和set。map是key-value形式,set是单值。map和set只能存放唯一的key,multimap和multiset可以存放多个相同的key。
容器类自动申请和释放内存,因此无需new和delete操作。
-
Vector
用到改知识的题目:(201709-4通信网络)
vector基于模板实现,需包含头文件vector。
//1.定义和初始化 vector<int> vec1; //默认初始化,vec1为空 vector<int> vec2(vec1); //使用vec1初始化vec2 vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2 vector<int> vec[100]; //每一个vec[i]是vector类型,vec[100]相当于一个二维数组。
//2.常用操作方法 vec1.push_back(100); //添加元素 int size = vec1.size(); //元素个数 bool isEmpty = vec1.empty(); //判断是否为空 cout<<vec1[0]<<endl; //取得第一个元素 vec1.insert(vec1.end(),5,3); //从vec1.back位置插入个值为的元素 //vec1.pop_back(); //删除末尾元素 //vec1.erase(vec1.begin(),vec1.end());//删除之间的元素,其他元素前移 cout<<(vec1==vec2)?true:false; //判断是否相等==、!=、>=、<=... //vec1.clear(); //清空元素
//3.遍历 int length = vec1.size(); for(int i=0;i<length;i++) { cout<<vec1[i]; } cout<<endl<<endl; |
二、list
List是stl实现的双向链表,与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。需要添加头文件list
//1.定义和初始化 list<int> lst1; //创建空list list<int> lst2(3); //创建含有三个元素的list list<int> lst3(3,2); //创建含有三个元素的list list<int> lst4(lst2); //使用lst2初始化lst4 list<int> lst5(lst2.begin(),lst2.end()); //同lst4
//2.常用操作方法 lst1.assign(lst2.begin(),lst2.end()); //分配值 lst1.push_back(10); //添加值 lst1.pop_back(); //删除末尾值 lst1.begin(); //返回首值的迭代器 lst1.end(); //返回尾值的迭代器 lst1.clear(); //清空值 bool isEmpty1 = lst1.empty(); //判断为空 lst1.erase(lst1.begin(),lst1.end()); //删除元素 lst1.front(); //返回第一个元素的引用 lst1.back(); //返回最后一个元素的引用 lst1.insert(lst1.begin(),3,2); //从指定位置插入个 lst1.rbegin(); //返回第一个元素的前向指针 lst1.remove(2); //相同的元素全部删除 lst1.reverse(); //反转 lst1.size(); //含有元素个数 lst1.sort(); //排序 lst1.unique(); //删除相邻重复元素
//3.遍历 //迭代器法 for(list<int>::const_iterator iter = lst1.begin();iter != lst1.end();iter++) { cout<<*iter; } cout<<endl; |
三、deque
deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。其余类似vector操作方法的使用。
-
Map
(201709-4通信网络)
C++中map容器提供一个键值对(key/value)容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。需要包含头文件map。Map会根据key自动排序。
//1.定义和初始化 map<int,string> map1; //空map
//2.常用操作方法 map1[3] = "Saniya"; //添加元素 map1.insert(map<int,string>::value_type(2,"Diyabi"));//插入元素 //map1.insert(pair<int,string>(1,"Siqinsini")); map1.insert(make_pair<int,string>(4,"V5")); string str = map1[3]; //根据key取得value,key不能修改 map<int,string>::iterator iter_map = map1.begin();//取得迭代器首地址 int key = iter_map->first; //取得eky string value = iter_map->second; //取得value map1.erase(iter_map); //删除迭代器数据 map1.erase(3); //根据key删除value map1.size(); //元素个数 map1.empty(); //判断空 map1.clear(); //清空所有元素
//3.遍历 for(map<int,string>::iterator iter = map1.begin();iter!=map1.end();iter++) { int keyk = iter->first; string valuev = iter->second; } |
-
Stack
stack 模板类的定义在<stack>头文件中。
stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型为deque。
定义stack 对象的示例代码如下:
stack<int> s1;
stack<string> s2;
stack 的基本操作有:
入栈,如例:s.push(x);
出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。
访问栈顶,如例:s.top()
判断栈空,如例:s.empty(),当栈空时,返回true。
访问栈中的元素个数,如例:s.size()。六、queue
queue 模板类的定义在<queue>头文件中。
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
定义queue 对象的示例代码如下:
queue<int> q1;
queue<double> q2;queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()Eg:
#include <cstdlib>
#include <iostream>
#include <queue>using namespace std;
int main()
{
int e,n,m;
queue<int> q1;
for(int i=0;i<10;i++)
q1.push(i);
if(!q1.empty())
cout<<"dui lie bu kong\n";
n=q1.size();
cout<<n<<endl;
m=q1.back();
cout<<m<<endl;
for(int j=0;j<n;j++)
{
e=q1.front();
cout<<e<<" ";
q1.pop();
}
cout<<endl;
if(q1.empty())
cout<<"dui lie bu kong\n";
system("PAUSE");
return 0;
}七、priority_queue
在<queue>头文件中,还定义了另一个非常有用的模板类priority_queue(优先队列)。优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。
priority_queue 模板类有三个模板参数,第一个是元素类型,第二个容器类型,第三个是比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队时序列尾的元素出队)。
定义priority_queue 对象的示例代码如下:
priority_queue<int> q1; priority_queue< pair<int, int> > q2; // 注意在两个尖括号之间一定要留空格。
priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队
priority_queue 的基本操作与queue 相同。初学者在使用priority_queue 时,最困难的可能就是如何定义比较算子了。如果是基本数据类型,或已定义了比较运算符的类,可以直接用STL 的less 算子和greater算子——默认为使用less 算子,即小的往前排,大的先出队。如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队列试图将两个元素x 和y 代入比较运算符(对less 算子,调用x<y,对greater 算子,调用x>y),若结果为真,则x 排在y 前面,y 将先于x 出队,反之,则将y 排在x 前面,x 将先出队。看下面这个简单的示例:
#include <iostream>#include <queue>
using namespace std;
class T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c)
{
}
};
bool operator < (const T &t1, const T &t2)
{
return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}
main()
{
priority_queue<T> q;
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top(); q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 1;
}
输出结果为(注意是按照z 的顺序从大到小出队的):
3 3 6
2 2 5
1 5 4
4 4 3
再看一个按照z 的顺序从小到大出队的例子:
#include <iostream>
#include <queue>
using namespace std;
class T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c)
{
}
};
bool operator > (const T &t1, const T &t2)
{
return t1.z > t2.z;
}
main()
{
priority_queue<T, vector<T>, greater<T> > q;
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top(); q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 1;
}
输出结果为:
4 4 3
1 5 4
2 2 5
3 3 6
如果我们把第一个例子中的比较运算符重载为:
bool operator < (const T &t1, const T &t2)
{
return t1.z > t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}
则第一个例子的程序会得到和第二个例子的程序相同的输出结果。