STL学习指南
优先队列(priority_queue)
初始化
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,大顶堆
priority_queue <int,vector<int>,less<int> >q;
priority_queue<int> q;//默认大顶堆
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
自定义类型
struct cmp {//方法一:(外部实现)堆栈自定义需要实现一个cmp结构体
bool operator()(pii a, pii b) {
return a.fi>b.fi;}
};
struct A //方法二(内部实现):运算符重载<
{
int x;
tmp1(int a) {x = a;}
bool operator<(const A& a) const
{
return x < a.x; //大顶堆
}
};
priority_queue<pii, vector<pii>, cmp> mi_hp;
队列(queue)
初始化
queue<T> q;
内置方法
push();
//元素入队的push操作只是制造了该元素的一个副本入队,因此在入队后对原元素的修改不会影响队列中的副本,而队列中副本的修改也不会改变原元素,需要注意由此可能引入的bug(一般由结构体产生)。
pop();
size();
empty();
front();
back();
双端队列(deque)
初始化
#include<deque>
deque<int> dq;
内置方法
//插入数据
dq.push_back();
dq.push_front();
//视图
dq.front();
dq.back();
//删除数据
dq.pop_back();
dq.pop_front();
distance(d.begin(),it)//可以求出当前的迭代器指针it距离头部的位置
遍历方法
for(const auto& elem:dq){
cout<<elem<<" ";
}
for(auto elem:dq){
cout<<elem<<" ";
}
列表(vector)
初始化
vector<int> e;//一维
vector<vector<int>> e(n,vector<int>(n));//二维
vector<PII> e;
vector<vector<vector<int>>> a(N,vector<vector<int> >(m,vector<int>(k,0)));//三维
vector<vector<array<int,27>>> a(n,vector<array<int,27>>(m));//array实现常数优化
//通过拷贝构造初始化
vector<int> v2=v1;
//使用部分元素构造
vector<int> v3(v1.begin(),v1.begin()+1);
内置方法
【元素个数】
当容器A为空时,如果直接使用A.size()-1的话,会直接造成溢出,得到的结果并不是-1,而是一个很大的数。
所以为了避免发生溢出的情况,需要正确使用size方法。
e.size();//返回值类型为unsigned int型,unsigned int的取值范围为0~2^32 -1。
int size = e.size();//1
(int)e.size();//2
【添加元素】
e.emplace_back(1,1);//会执行构造函数
e.push_back(1);
【列表复制】
//1
vector<int> v1(v2);
//2
vector<int> v1;
v1.assign(v2.begin(),v2.end());
【删除元素】
//删除末尾元素
v1.pop_back();
//删除指定位置的一个元素或删除指定范围内的元素(迭代器)
v.erase( vec.begin() + 5 );//删除第6个元素
vec.erase( vec.begin(), vec.begin() + 3 );//删除第1个元素,到第4个元素
【遍历元素】
//正向迭代器
(vector<int>::iterator it=v.begin();i!=v.end();i++){
cout<<*it;
}
//逆向迭代
for(vector<int>::reverse_iterator it=v1.rbegin();it!=v1.rend();it++)
cout<<*it<<" ";
[清空vector]
vector<int> v;
v.clear();
[批量递增赋值vector]
#include <numeric> //iota头文件
vector<int> a(10);
iota(a.begin(),a.end(),1);// c++20:从1开始赋值
字符串(string)
初始化
string s=string(n,'*');//复制n次,字符复制n次。
内置函数
//截取字串
string s="123123";
string sub=s.substr(0,5);//从起始位置0截取长度为5的子串
//查询单个字符
bool flag=s.find(c)!=string::npos;
[比较字符串相似性]
[c++20]
string s;
bool flag=equal(s.begin() + 1, s.end(), s.begin());// Returns true if the range [first1, last1) is equal to the range [first2, first2 + (last1 - first1)), and false otherwise.
bool flag=equal(s1.begin(),s1.end(),s2.begin(),s2.edn());// Returns true if the range [first1, last1) is equal to the range [first2, last2), and false otherwise.
[实现有序]
单个字符串排序
string s;
sort(s.begin(),s.end());
字符串数组排序
string a[n];
sort(a,a+n);// 可直接使用 sort,无需重写cmp方法,因为 string 类对 '>' ,'==', '<' 这些比较运算符进行了重载。
[字符串转为整数]
#include<stdlib.h>
int atoi(cosnt char* str);
//atoi() 会扫描str字符串,跳过前面的空格字符,直到遇到数字或正负号才开始做转换,
//而遇到非数字或字符串结束符(’\0’)才结束转换,并将结果返回返回值。
char str1[] = "-10";
int num1 = atoi(str1);//-10
char str1[] = "abc-1100def";// num1=0
二进制哈希(bitset)
初始化
#include <bitset>
std::bitset<N> bitset1; // 创建一个长度为 N 的 bitset,所有位都被初始化为 0
std::bitset<N> bitset2(value); // 使用二进制整数 value 初始化一个长度为 N 的 bitset
std::bitset<N> bitset3(string); // 使用二进制字符串 string 初始化一个长度为 N 的 bitset
std::bitset<N> bitset4(bitset); // 使用另一个 bitset 初始化一个长度为 N 的 bitset
//int(4位)
bitset<sizeof(int)> bits;
内置方法
//可以直接输出,二进制字符串
cout<<bits;
无序字典(unordered_map)
初始化
#include <unordered_map>
unordered_map<int,int> up;
有序字典(map)
底层采用的是树型结构(红黑树)
多数使用平衡二叉树
有序,不重复
初始化
map<int,int> p;
基本操作
插入元素
map1.insert(pair<int,string>(1,"ta"));
map1.insert(make_pair(2,"he"));
map1.insert(map<int,string>::value_type(3,"wo"));
map1[4]="ha";
删除元素
for(map<int,string>::iterator it=map1.begin();it!=map1.end();it++){
if(it->second.compare("ll")==0){
map1.erase(it);
}
}
查找元素
find
equal_range
map<int,string>::iterator it=map1.find(100);//返回迭代器的指针位置
pair<map<int,string>::iterator,map<int,string>::iterator> m=map1.equal_range(1);
//第一个属性为小于等于1的迭代器位置,第二个为大于1的迭代器位置
//遍历
map<int> p;
for(auto &entry:p){
int key=entry.first;
int val=enrty.second;
}
有序哈希(set)
数据结构特性
用来判断一个元素是否在一个组里,底层数据结构为红黑树,有序,不重复。
初始化
set<int>默认创建从小到大的int类型集合
set<int,less>创建从小到大的int类型集合
set<int,greater>创建从大到小的int类型集合
基本操作
s.insert(1);
//插入:插入重复元素,判为失败,返回一个pair类型`pair<iterator,bool>`
//复杂类型数据,需要通过仿函数来确定元素顺序,判断是否是重复元素
s.empty();
s.erase(1);
set<int>::iterator it=s.begin();
s.erase(*it)
查找元素
set<int> s;
s.insert(1);
set<int>::iterator it0=s.find(1);//查找元素为1的迭代器位置
set<int>::iterator it1=s.lower_bound(1);//查找小于等于1的迭代器位置
set<int>:: iterator it2=1.upper_bound(1);//查找大于等于1的迭代器位置
pair<set<int>::iterator,set<int>::iterator> m=s.equal_range(1);
//第一个属性表示大于等于1的迭代器位置,第二个是大于1的迭代器位置
重复有序哈希(multiset)
初始化
multiset<int> p;
multiset<int,less<int>>set1;//升序
multiset<int, greater<int>>set1;//降序
基本操作
//插入一个数
p.insert(x);
p.emplace(x);
//访问第一个数,也是最值
int x=*st.begin();
//查找第2大值
*(prev(s.end(),2);//当“n“为正数时,返回传入迭代器“iterator”左边,
//当“n“为负数时,返回传入迭代器“iterator”右边,
//删除第一个数
p.extract(p.begin());
p.erase(p.begin());
//删除元素为x的全部副本
p.erase(x);
数组(array)
初始化
array<int,10> a;//因为长度固定,这里的元素个数不能是变量。
基本操作
a.front();//返回数组第一个元素的引用
a.back();//返回数组最后一个元素的引用
栈(stack)
初始化
stack<int> st;
基本操作
s1.push();//压栈
s1.empty();//判空
s1.top();//视图
s1.size();//大小
s1.pop();//出栈
双向链表(list)
数据结构特性
相当于java的LinkedList
支持很好的效率任意地方的删除和插入
不支持随机访问
初始化
list<int> p;
基本操作
push_front()//头插入元素
push_back()//尾插入元素
erase()//通过位置或者区间来删除,主要结合迭代器指针来操作
remove()//通过指定值来删除
l.erase(l.begin());
l.remove(100);
遍历方法
for(list<int>::iterator it=l.begin();it!=l.end();it++)
cout<<*it<<" ";