C++STL常用库的详解和应用
STL简介
STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。现在虽说它主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间。STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类。组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。
接下来,我主要介绍常用的几个库:<vector>、<map>、<queue>、<stack>的主要函数和使用方法
stack 栈
栈是一种常用的数据结构,原理就是:后进先出。插入和删除元素都是从栈顶元素开始。插入元素叫做入栈,删除元素叫做出栈,是一个用的特别多的结构
#include<stack> 导入,主要函数下面代码里面有说明
#include <iostream>
#include<stack>
using namespace std;
int main()
{
stack<int> s;
s.push(1); //入栈
s.push(2);
s.push(3);
s.push(34);
cout << s.top() << endl; //栈顶元素
s.pop(); //出栈
cout << s.top() << endl;
s.push(23);
cout << s.top() << endl;
while (!s.empty()) { //栈是否为空,栈为空则真
cout << s.size() << endl; //栈的大小
cout <<s.top()<< endl;
s.pop();
}
}
queue 队列
队列也是一种特别常见的数据结构,先进先出,在队尾增加,从队首删除
#include <iostream>
#include<queue>
using namespace std;
int main()
{
queue<int>q;
for (int i = 0; i < 10; i++) {
q.push(i); //队尾加入元素
}
cout << q.front() << " " << q.back() << endl; //队首和队尾
cout << q.empty() << " " << q.size() << endl; //队列是否为空 队列的长度
q.pop(); //队首删除元素
cout << q.front()<< endl;
q.pop();
cout << q.front()<< endl;
cout << q.back() << endl;
q.push(852);
cout << q.back() << endl;
}
priority_queue 优先级队列
优先级队列,使用了最大堆的结构,元素从大到小一次排列,就像一条排好的队伍,它也在queue函数库里面
#include <iostream>
#include<queue>
using namespace std;
int main()
{
priority_queue<int>pq;
pq.push(2);
pq.push(1);
pq.push(50);
pq.push(8);
pq.push(5);
cout << pq.size() << endl;
while(!pq.empty()){
cout << pq.top() << endl;
pq.pop();
}
}
map 容器
Map是STL的一个关联容器,它提供一个一一对应关系(其中第一个可以称为键(Key),每个键只能在map中出现一次,第二个称为值(Value),就像房间钥匙(Key)和房间(Value)一一对应一样。由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。按照key的升序排列
因为map一般是用pair进行初始化的,所以我这里简单提一提 pair 一个常用的结构体,有点像map,主要是用于将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
#include <iostream>
using namespace std;
int main()
{
pair<int, double>p; //初始化
p.first = 1;
p.second = 2;
cout << p.first << " " << p.second << endl;
pair<int, double>p2(1, 5.3); //初始化
cout << p2.first << " " << p2.second << endl;
return 0;
}
map的函数和具体用法
#include <iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
map<int, string>m;
m.insert(pair<int, string>(1,"good")); //利用pair 进行初始化
m[2] = "hello"; //也可以这样初始化 用数组方式插入数据
m[3] = "gell";
m.insert(pair<int, string>(4, "a"));
cout << m.size() << endl;
for (map<int, string>::iterator it = m.begin(); it != m.end(); it++) { //使用迭代器进行搜索
cout <<it->first<<" "<<it->second << endl;
}
//用 count 函数来判断 key 是否出现,因为key 是唯一的,所以 若出现则输出1 没有出现则输出0
cout << m.count(1) << endl; //判断是否存在 key==1
//用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
if (m.find(7) == m.end()) {
cout << "找不到 key值" << endl;
}
m.erase(1); //根据key进行元素删除
// m.clear() 删除全部元素
if (m.find(1) == m.end()) {
cout << "key 已经被删除了" << endl;
}
return 0;
}
vector 动态数组
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{ //向量,动态数组
vector<int>a(10); //声明一个初始大小为10的向量
vector<int>v(10,1); //声明一个初始化大小为10的向量,初始值为1
vector<int> obj;
obj.push_back(1);//加入到最后面
obj.push_back(5);
obj.push_back(2);
obj.push_back(3);
//迭代器来访问
for (vector<int>::iterator it = obj.begin(); it != obj.end(); it++) {
cout <<*(it) <<" ";
}
cout << endl;
//用数组的方式来访问
for (int i = 0; i < obj.size(); i++) {
cout << obj[i] <<" ";
}
obj.pop_back(); //删除最后一个元素
cout << endl;
for (int i = 0; i < obj.size(); i++) {
cout << obj[i] << " ";
}
cout << endl;
cout <<obj.front()<<" "<<obj.back() << endl; //得到头部和尾部
cout << obj.at(1) << endl; //得到下标为1的数据 就是相当于 obj[1]
sort(obj.begin(), obj.end()); //从小到大,一定是用迭代器来排序
for (int i = 0; i < obj.size(); i++) {
cout << obj[i] << " ";
}
cout << endl;
reverse(obj.begin(), obj.end()); //从大到小,一定是用迭代器来排序
for (int i = 0; i < obj.size(); i++) {
cout << obj[i] << " ";
}
cout << endl;
vector<vector<int>> o(10); //十行的动态数组
// vector<vector<int> > obj(N, vector<int>(M)); //定义二维动态数组5行6列
for (int i = 0; i < o.size(); i++) {
o[i].resize(5); //m每一行五列
}
for (int i = 0; i < o.size(); i++) {
for (int j = 0; j < o[i].size(); j++) {
cout << o[i][j]<<" ";
}
cout << endl;
}
// vector<int> e[10] 也是一个二维数组,不过还没有对具体e[0]进行空间分配
return 0;
}