C++ STL(Standard Template Library)学习汇总

目录

STL(Standard Template Library)学习汇总

1.为什么选择STL?

2.STL—vector

3.STL—stack(栈 后进先出)

4.STL—queue(队列 先进先出)

5.STL—priority_queue(优先队列)

6.STL—map(映射)

7.STL—set

8.STL—string


STL(Standard Template Library)学习汇总

1.为什么选择STL?

STL的可读性极佳,运用极广,被选为GNU C++的标准程序库,又开放自由运用。不仅最为人广泛运用的各种数据结构和算法在STL中有良好的实现,连内存配置与管理也都重重考虑了最佳效能。一切的一切,除了实现软件积木的高度复用性,让各种组件得以灵活搭配运用,更考虑了实现上的关键议题:效率

2.STL—vector

vector的概念:

vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。vector的数据安排及操作方式与array非常相似,唯一的差别在于array是静态空间,一旦配置了就不能改变;vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。vector不是一种数据类型,而只是一个类模版,可以用来定义多种数据类型。在定义了vector对象之后,vector类型的每一种都指定了其保存元素的类型。

vector的头文件:#include <vector>

vector的声明:

vector < int > v; // 定义一个空的vector,vector可以存放任意类型的数据

vector < int > v[100]; //相当于二维数组,大多数用于临界表的建立,v[i]代表从i出发的边,vector里存的是边

vector < int > v(4,5); // 定义了一个大小为4的vector 初始化为5

vector < int > v{1,2,-3,4,7,8}; // 定义一个vector 里面含有 1,2,-3,4,7,8

vector的方法: 

push_back() //在数组尾部添加一个元素

pop_back() //去掉数组最后一个元素

erase() // 删除一个元素

resize(5) //重置大小,不赋值默认为0

front() //获得数组第一个元素

*v.begin()  // 获得第一个元素

back() // 获得最后一个元素

size() // 获得元素个数

vector的遍历:

首先我们应该知道什么是迭代器: 它你可以理解为指针

//迭代器:
for(vector < int > :: iterator it = v.begin(); it != v.end(); it++) 
    cout<<*it; //迭代器循环​​
//迭代器简化:
for(auto it = v.begin(); it != v.end(); it++) 
    cout<<*it; //迭代器简化循环​​​​​
//c++11新特性:
for(auto x:v) cout<<x; // c++11新特性

vector的排序与反转:

首先我们要知道algorithm:algorithm是对容器继承的一些算法函数,辅助刷算法题。

排序:

//使用sort函数:
sort(v.begin(),v.end(),less<int>()); //从小到大
sort(v.begin(),v.end(),greater<int>()); //从大到小排序

反转:

//使用reverse函数:
reverse(v.begin(), v.end());//元素翻转

vector的获取元素:

vector < int > v{1,2,-3,4,7,8};

cout<<v[4] // 获得元素 7

cout<<v.at(3) // 获得元素 4

3.STL—stack(栈 后进先出)

stack的概念:

stack即栈,允许新增元素、移除元素、取得最顶端元素。但除了最顶端外,没有任何其他方法可以存取stack的其他元素,stack不允许随机访问。stack所有元素的进出都必须符合后进先出的条件,只有stack顶端的元素,才有机会被外界取用。stack不提供走访功能,也不提供迭代器。

stack的头文件:#include <stack>

stack的声明:

stack < type > s; //可以存放任意类型的数据

stack的方法:

push() // 压入一个元素

pop() // 弹出一个元素

top() // 获取栈顶元素

size() //获取元素个数

empty() // 有元素为false  无元素为true

运用stack的经典例子:

进制转换(十进制转二进制)

int change(int number) {
	stack <int> s;
	int ans = 0;
	while(number > 0) {
		s.push(number % 2);
		number /= 2;
	}
	while(!s.empty()) {
		ans = ans * 10 + s.top();
		s.pop();
	}
	return ans;
}

单词逆序(拓展sstream)

输入 :I love ACM

输出:ACM love l

#include <iostream>
#include <stack>
#include <sstream>
using namespace std;
int main(){
   	string str;
   	stack <string> s;
   	getline(cin,str);
   	stringstream ss;
   	ss<<str;
   	while(ss>>str) {
   		s.push(str);
	}
	while(!s.empty()) {
		cout<<s.top();
		s.pop();
		if(s.size() != 0) cout<<" ";
	}
	return 0;
}

4.STL—queue(队列 先进先出)

queue的概念:

queue即普通队列,允许新增元素、移除元素、从最底端加入元素、取得最顶端元素。但除了最底端可以加入、最顶端可以取出,没有任何其他方法可以存取queue的其他元素。queue不支持随机访问。

queue的头文件:#include <queue>

queue的声明:

queue < type > Q; //可以存放任意类型

queue的方法:

Q.empty();// 查看是否为空,如果为空返回true

Q.push();// 在队尾增加元素

Q.pop();// 弹出队首第一个元素

Q.size();//显示队列中现有元素数量

Q.front();//显示队首第一个元素

Q.back();//显示队尾最后一个元素

5.STL—priority_queue(优先队列)

priority_queue的概念:

优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)priority_queue允许用户为队列中存储的元素设置优先级。这种队列不是直接将新元素放置在队列尾部,而是放置在比它优先级低的元素前面,即提供了一种插队策略。标准库默认使用<操作符来确定他们之间的优先级关系,即权重大的排在队首。

priority_queue的头文件:#include <queue>

priority_queue的声明:

priority_queue<type, container, comp> Q;

type为队列操作的数据类型;container为实现队列所用的容器类型,必须是用数组实现的容器,比如 vector, deque 但不能用 list;comp为排队策略。

priority_queue<int, vector<int>, less<int> > Q;

priority_queue 模板类有三个模板参数,第一个是元素类型,第二个是保存数据的容器,第三个是比较方式。其中后两个都可以省略,默认容器为vector,默认的比较方式是数值上的小于关系,即用operator<,此时队列中元素由队头到队尾从大到小排列,如果把后面两个参数缺省的话,优先队列就是大根堆,队头元素最大。(注意这里的大根堆并不是数据结构意义上的大根堆。priority_queue只是保证第一个结点最大)

构造举例子:

/*
前两个参数没什么说的,很好理解,其中第三个参数,默认有三种写法,小顶堆:greater、大顶堆:less;
如果想自定义优先级而type不是基本类型,而是复杂类型,例如结构体、类对象,则必须重载其中的operator()。
*/
/*基本类型*/
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int main() {
	priority_queue <int> Q1; //默认大根堆 
	priority_queue <int,vector<int>,greater<int>> Q2; //小根堆 
	priority_queue <int,vector<int>,less<int>> Q3; //大根堆 
} 

/*复杂类型*/
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
struct Node{
	//以距离长短为依据的自定义小根堆 
	int dis,pos;// dis为最短距离,pos为是编号 。 
	bool operator <(const Node &x) const {
		return x.dis < dis; // 小根堆   
		//return x.dis > dis //大根堆 
	}
};
int main() {
	priority_queue <Node> Q4; //自定义小根堆 
} 

priority_queue的方法:

priority_queue <int> Q;  

Q.empty();//判断是否为空

Q.size();//优先队列中元素个数

Q.pop();//删除队首元素

Q.top();//查看优先级最高的元素

Q.push();//进入队列中对应优先级的位置 

6.STL—map(映射)

map的概念:

map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value。map中所有元素都会根据元素的Key自动被排序。同时map不允许两个元素有相同的键值。

map的头文件#include<map>

map的声明:

map <int,string> M;

map的使用:

插入元素:

map <int,string> M;
//使用insert函数插入pair 
M.insert(pair<int,string>(111,"mapmap"));
//使用insert函数插入value_type数据 
M.insert(map<int,string>::value_type(222,"lili"));
//使用array的方法插入 
M[333] = "sisi";

寻找元素:

/* 如果M中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回结束游标end()。*/
map <int,string>::iterator it = M.find(k);

/*返回m中键值等于k的元素的个数。*/
int cnt = M.count(k);
/*
对于map对象,由于map中不存在相同的两个或者多个键,所以count成员的返回值只能是0或者1,用于检查map对象中某键是否存在。
find成员返回的是指向元素的迭代器,如果元素不存在,则返回end迭代器。
*/

删除元素:

int ans = M.erase(k);  // 删除m中键为k的元素,返回size_type类型的值,表示删除元素的个数。
map <int,string>::iterator it = M.erase(p);  
//从m中删除迭代器p所指向的元素,p必须指向m中确实存在的元素,
//而且不能等于m.end(),返回void类型。

清空元素:

//用迭代器范围刪除 : 把整个map清空
M.erase(M.begin(), M.end());
//使用函数清空
M.clear();

map基本函数:

M.begin();//返回指向map头部的迭代器 
M.end();//返回指向map末尾的迭代器
M.size();//返回map中元素的个数
M.rbegin();//返回一个指向map尾部的逆向迭代器
M.rend();//返回一个指向map头部的逆向迭代器
M.max_size();//返回可以容纳的最大元素个数

map的遍历:

有三种遍历方法具体如下:

#include <iostream>
#include <algorithm>
#include <map> 
using namespace std;
int main() {
	//构造map 
	map <int,string> M;
	//使用insert函数插入pair 
	M.insert(pair<int,string>(1,"mapmap"));
	//使用insert函数插入value_type数据 
	M.insert(map<int,string>::value_type(4,"lili"));
	//使用array的方法插入 
	M[3] = "sisi";
	M[2] = "kkkccc";
	
	map <int,string>::iterator it;//迭代器
	
	//方法一:利用迭代器 
	for(it = M.begin(); it != M.end(); it++)
		cout<<it->first<<" "<<it->second<<endl;  
	//方法二:利用反向迭代器  
	for(it = M.rbegin(); it != M.rend(); it++)
		cout<<it->first<<" "<<it->second<<endl;  
	//方法三:数组遍历
	for(int i = 1; i <= M.size(); i++) 
		cout<<M[i]<<endl;
    return 0;
} 

7.STL—set

set概念:

map容器是键值对的集合,而set容器只是单纯的键的集合,当只想知道一个值是否存在时,使用set容器是最合适的。在set中,所有元素都会根据其键值被自动排序,同时set中不允许两个元素有相同的键值。

set的头文件#include <set>

set的声明:

set < type > S;  // 创建一个名为S的空set,type是类型名。

set的使用: 

插入数据:

s.insert(key_value); 
/*将key_value插入到set中,返回值是pair<set<int>::iterator, bool>,bool标志着插入是否成功,而
iterator代表插入的位置,若key_value已经在set中,则iterator表示key_value在set中的位置。如果
key_value不存在,则插入;否则不进行任何操作。 */

s.insert(iter, key_value); 
//在指定的迭代器位置插入key_value,返回该迭代器。 

s.insert(begin, end); 
//将迭代器begin到end之间的元素插入到set中,返回值是void。

查找数据:

s.count(k); 
/*返回s中键值等于k的元素的个数,这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样
就变成了判断某一键值是否在set出现过了。*/
s.find(k); 
//如果查找到键值k,则返回该键值的迭代器位置;否则,返回集合最后一个元素后面的一个位置,即end()。

删除数据:

s.erase(key_value);  // 删除键值为key_value的值
s.erase(iter);  // 删除迭代器iter所指向的元素
s.erase(iterator first, iterator last);  // 删除两个迭代器之间的值

set的基本方法:

S.begin();  // 返回set容器的第一个元素。
S.end();  // 返回set容器的最后一个元素的下一个位置。
S.clear();  // 删除set容器中的所有的元素。
S.empty();  // 判断set容器是否为空。
S.max_size();  // 返回set容器可能包含的元素最大个数。
S.size();  // 返回当前set容器中的元素个数。
S.rbegin();  // 返回set容器的最后一个元素。
S.rend();  // 返回set容器的第一个元素的前一个位置。
S.erase(); // 删除迭代器iter所指向的元素

8.STL—string

前言:

string类本不是STL的容器,但是它与STL容器有着很多相似的操作,因此,把string放在这里一起进行介绍。 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下的需要。我们尽可以把它看成是C++的基本数据类型。 

string的头文件#include <string>

string的声明:

string s;  // 生成一个空字符串s 

string s(str) ; // 拷贝构造函数生成str的复制品

string基本对象操作:

string s;
s.empty(); // s为空串 返回true
s.size();  // 返回s中字符个数 类型应为:string::size_type
s[n];      // 从0开始相当于下标访问
s = s1+s2; // 把s1和s2连接成新串 返回新串
s1=s2;     // 把s1替换为s2的副本
s1==s2;    // 比较,相等返回true
`!=, <, <=, >, >=`  //惯有操作 
//当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的:
string s1(“hello”);
string s3=s1+”world”;  //合法操作
string s4=”hello”+”world”;  //非法操作:两个字符串字面值相加

string的方法:

str.empty(); //判空
str.length(); //字符串长度
str.clear(); //清空字符串 
str.find(tmpstr); //在字符串中检索字符串tmpstr是否存在。
str.swap(tmpstr); //交换两个字符串的内容
sort(str.begin(),str.end()); //字符串排序 
reverse(str.begin(),str.end()); //字符串反转 
to_string(str);//数字转字符串
stoi(str);//字符串转数字
atoi(str.c_str());//字符串转数字

小案例:

stringint的转换:

#include <iostream>
#include <algorithm>
#include <sstream>
#include <string> 
using namespace std;
int main() {
    int n=0;
	string result="10000";  
	stringstream st;
	st<<result;
	st>>n;  // n等于10000
	cout<<(n + 10)<<endl; //运行结果为10010
	return 0;
} 

int到string的转换:

//方法一:
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string> 
using namespace std;
int main() {
	int n = 20210506;
	string str = "";  
	stringstream st;
	st<<n;
	str = st.str();
	cout<<(str + 'A')<<endl; //结果为20210506A
	return 0;
} 

//方法二:
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string> 
using namespace std;
int main() {
	int n = 20210506;
	string str = "";  
	str = to_string(n);
	cout<<(str + 'A')<<endl; 
	return 0;
} 

完美撒花!!!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@李思成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值