STL常见用法
STL是一套非常好用的C++模板, 其中内置了很多已经封装好的数据结构和算法. 如果每次都要从头实现很麻烦, STL在刷算法题时候很好用. 本文是参照steve-yu视频做下的笔记.
输入输出
C++保留了原来C语言的输入和输出, 在基础上增加了cin和cout.
// 导入cin cout头文件
#include <iostream>
// c程序中输入输出
int a;
scanf("%d", &a);
printf("%d", a);
// C++输入输出
int a;
cin >> a;
cout << a;
// 连续输入输出变量
int a, b, c;
cin >> a >> b >> c;
cout << a<<b << c;
// 换行方便
cout << a<< endl;
cin和cout的效率是比scanf和printf低很多的, 在刷算法题时, 尽可能使用C语言的输入输出来避免超时.
头文件
在使用任意的STL数据类型前, 都需要导入对应的头文件. 比如说使用vector
就必须导入<vector>
. <algorithm>
中有许多内置好的算法, 例如sort
, reverse
等.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[]={2,1,5,0,-1,5,9};
sort(a,a+7);
for(int i=0;i<7;i++)
cout<<a[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
String
字符串可以看做是char*的封装.
// c语言中的字符串定义和打印
char ch[]="asdkajbf";
for(int i=0;ch[i]!='\0';i++) printf("%c", *(ch+i));
// c++
string s = "zxcvbnm";
cout<< s <<endl;
获取一行字符串:
// c
scanf("%s", ch);
// c++
string s;
getline(cin, s);
cout << s;
还可以使用+=
运算, 数字会被转换成asc码.
string s;
s += "hello";
s += " world";
s += '5';
s += 10;//10对应的asc码是换行
int a = 5;//想把a加入字符串
s += (a+'0');
cout << s;
同样也可以进行排序:
string s = "5418340";
sort(s.begin(), s.end());
cout << s;
使用erase
和substr
:
// erase
string s = "5418340";
s.erase(s.begin());//删除第一个
s.erase(--s.end());//删除最后一个
cout << s;
// substr
string s = "5418340";
s = s.substr(1, 3);//取418,取索引为1,往后截断3个
s = s.substr(1, -1);//索引为1,截断到最后
cout << s;
Vector
vector
是封装好的向量, 类似数组. 使用前需导入vector
头文件.
vector<int> v;//定义一个空vector
vector<int> v2(4);//定义一个4个大小的vector,初始为0
vector<int> v3(4,6);//定义一个4个大小的vector,初始为6
vector<int> v{1,2,3,4,5};//定义一个vector,数字为1,2,3,4,5
获取元素:
vector<int> v{1,2,3,4,5};
cout << v[1];//取索引为1
cout << v.at(2);//取索引为2的
// 获取第一个
cout<<v.front();
cout<<v[0];
cout<<*v.begin();
// 获取最后一个
cout<<v.back();
cout<<v[v.size()-1];//size是获取大小
cout<<*--v.end();
添加元素:
vector<int> v;
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(6);
修改形状:
v.resize(10);
删除元素:
v.erase(v.begin());//删除第一个元素
v.erase(--v.end());//删除最后一个元素
向量排序:
vector<int> v{5,1,2,5,4,0,-1};
sort(v.begin(),v.end(),less<int>());//从小到大
sort(v.begin(),v.end(),greater<int>());//从大到小排序
Stack
就是数据结构中的栈, 先进后出. 使用前需导入stack
头文件.
stack<int> s;
栈的各种操作:
s.push(2); // 入栈
s.push(3);
cout << s.top() << endl; // 获取顶端
s.pop(); // 出栈 无返回值
cout << s.top() << endl;
cout << s.size() << endl; // 查看元素个数
用栈实现进制转换(decimal to binary):
int itob(int decimal){
stack<int> s;
int res = 0;
while(decimal != 0){
// 除二取余
s.push(decimal%2);
decimal /= 2;
}
while(!s.empty())}{
res = res * 10 + s.top();
s.pop();
}
return res;
}
用栈实现逆序单词打印:
#include <stack>
#include <sstream>
void inverse(string str){
stack<string> s;
stringstream ss;
ss << str; // 让字符串流入stringstream
while(ss >> str){
s.push(str);
}
while(!s.empty()){
cout << s.top();
s.pop();
if(s.size()!=0) cout << " ";
}
}
这里使用了stringstream
, 用来做数据转换, 十分安全和方便. 例如字符串转数字:
// 方法1
string s = "1234";
int i;
stringstream ss;
ss << s;
ss >> i;
cout << i;
// 方法2
string s = "1234";
int i = stoi(s);
cout << i;
数字转字符串:
// 方法1
int a = 1234;
string out;
stringstream ss;
ss << a;
ss >> out;
cout << out << endl;
//方法2(c++ 11)
int a = 1234;
cout << to_string(a) << endl;
Queue
此为队列的封装实现. 使用前需要导入<queue>
.
queue<int> q;
其操作为:
q.push(5); //入队
q.push(6);
cout<<q.front()<<endl; // 取队首
q.pop(); // 出队
cout<<q.front()<<endl;
cout<<q.size()<<endl; // 查看队列已有元素长度
Map
map
是一个映射关系(键值对). 这里的map
分为两种, 一种是有序的map
, 一种是无序的unordered_map
. 使用前都需要分别导入.
map:
map<int,int> m;//有序, 底层为树状结构
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<endl;
for(auto tmp:m){
cout<<tmp.first<<" "<<tmp.second<<endl;
}
unordered_map:
unordered_map<int,int> m;//无序, 底层为哈希结构
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<endl;
for(auto tmp:m){
cout<<tmp.first<<" "<<tmp.second<<endl;
}
pair的用法, 是一个映射结构.
bool cmp(pair<int,int> a,pair<int,int> b){
return a.first>b.first;
}
int main(){
unordered_map<int,int> m;//无序, 底层为哈希结构
m[6]=3;
m[5]=8;
m[4]=9;
vector<pair<int,int>> v(m.begin(),m.end());
sort(v.begin(),v.end(),cmp);
for(auto tmp:v){
cout<<tmp.first<<tmp.second<<endl;
}
return 0;
}
Set
它是集合的封装实现, 同样存在一种有序结构set
和一种无序结构unordered_set
. 使用前需要分别导入.
set<int> s;//树状结构 有序
unordered_set<int> s2;//哈希结构 无序
s.insert(3);
s.insert(4);
s.insert(4);
s.insert(4);
cout<<s.size()<<endl;
for(auto tmp:s)
cout<<tmp<<" ";
cout<<endl;
for(auto it=s.begin();it!=s.end();it++)
cout<<*it<<" ";
cout<<endl;
Deque
此为双端队列的封装实现, 使用前需要导入<deque>
.
deque<int> d;
// 4 9 1 2
d.push_back(1); // 尾部添加
d.push_back(2);
d.push_front(9); // 首部添加
d.push_front(4);
d.pop_back(); // 尾部删除
d.pop_front(); // 头部删除
for(auto tmp:d) cout<<tmp<<endl;
for(auto it=d.begin();it!=d.end();it++) cout<<*it<<endl;
sort(d.begin(),d.end(),greater<int>()); // 排序
List
此为双向链表的实现, 使用前需要导入<list>
.
list<int> li;
li.push_back(6); // 末尾插入
li.push_front(5); // 头部插入
li.emplace_front(9); // 也是头插
li.emplace_back(10); // 也是尾插
li.insert(++li.begin(),2); // 第一个元素后插入
for(auto tmp:li) cout<<tmp<<endl;
for(auto it=li.begin();it!=li.end();it++) cout<<*it<<endl;
//排序不能使用头文件algorithm中的sort 使用list模板自定义的sort方法
li.sort(greater<int>()); //从大到小排序