检查容器是否empty
不要使用过期的iterator
string
字符串转数字:
stoi(字符串,起始位置,n进制),将n进制的字符串转化为十进制
stoi(str, 0, 2);
string s="1234";
int i=stoi(s);
cout<<i;
————————————————
string s="1234";
int i;
stringstream ss;
ss<<s;
ss>>i;
cout<<i;
数字转字符串:
int a=1234;
string out;
stringstream ss;
ss<<a;
ss>>out;
cout<<out<<endl;
————————————————
int a=1234;
cout<<to_string(a)<<endl;
string::iterator || string::const_iterator
const_iterator begin()const; iterator begin();
const_iterator end()const; iterator end();
const_iterator rbegin()const; iterator rbegin();
const_iterator rend()const; iterator rend();
rbegin和rend用于从后向前的迭代访问,通过迭代器string::reverse_iterator||string::const_reverse_iterator实现
for(auto it=str.begin();it!=str.end();++it) <==> for(auto x:str)
string s;
getline(cin,s);
cout<<s;
string s="Hello World!";
s+=10;
s+='7'; <==> int a=7;s+=(a+'0');
string(const char *s);
string(int n,char c);
string s1;
string s2="hello";
'const' char &operator[](int n)'const';
'const' char &at(int n)'const';
at函数提供范围检查-越界抛出out_of_range异常, 下标运算符[]不提供检查访问
const char *data()const;
const char *c_str()const;
string s2 = s1.c_str();
int copy(char *s, int n, int pos = 0) const;
将当前串以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目
通过#include <sstream>头文件中定义的ostringstream和istringstream变量实现
string input("hello,this is a test");
istringstream is(input);
string s1,s2,s3,s4;
is>>s1>>s2>>s3>>s4;
ostringstream os;
os<<s1<<s2<<s3<<s4;
cout<<os.str();
int capacity()const;
int max_size()const;
int size()const;
int length()const;
bool empty()const;
void resize(int len,char c);
getline(istream &in,string &s);从输入流in中读取字符串到s中,以换行符'\n'分开
string substr(int pos=0,int n=npos)const;
void swap(string &s2);
string &assign(const string &s,int start,int n);
string &append(const string &s,int pos,int n);
int compare(int pos,int n,const string &s,int pos2,int n2)const;
iterator erase(iterator it);
iterator erase(iterator first, iterator last);
string &erase(int pos=0,int n=npos);
find()——查找失败返回string::npos的值
if (str1.find(str2) != string::npos)
cout << "str1 contains str2" << endl;
else
cout << "str1 does not contain str2" << endl;
int find(char c, int pos = 0) const;
int find(const char *s,int pos = 0) const;
int find(const char *s, int pos, int n) const;
int find(const string &s,int pos = 0) const;
int rfind(const string &s,int pos = npos) const;
int find_first_of(const string &s,int pos = 0) const;
int find_first_not_of(const string &s,int pos = 0) const;
int find_last_of(const string &s,int pos = npos) const;
int find_last_not_of(const string &s,int pos = npos) const;
replace()
string &replace(int p0, int n0,const char *s);
string &replace(int p0, int n0,const char *s, int n);
string &replace(int p0, int n0,const string &s);
string &replace(int p0, int n0,const string &s,int pos,int n);
string &replace(int p0, int n0,int n, char c);
string &replace(iterator first0, iterator last0,const char *s);
string &replace(iterator first0, iterator last0,const char *s, int n);
string &replace(iterator first0, iterator last0,const string &s);
string &replace(iterator first0, iterator last0,int n, char c);
string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);
insert()
string &insert(int p0, const char *s);
string &insert(int p0, const char *s, int n);
string &insert(int p0,const string &s);
string &insert(int p0,const string &s, int pos, int n);
string &insert(int p0, int n, char c);
iterator insert(iterator it, char c);
void insert(iterator it, const_iterator first, const_iterator last);
void insert(iterator it, int n, char c);
vector
vector<int> v;
vector<int> v(3);
vector<int> v(3,7);
vector<int> v{1,2,3,4,5};
cout << v[2] || v.at(2);
v.push_back(7);
v.resize(10);
v.erase(v.begin());
v.erase(--v.end());
v.front() || v[0] || *v.begin();
v.back() || v[v.size()-1] || *--v.end();
vector<int> v{1,3,5,-1,4,3,2,0};
sort(v.begin(),v.end(),less<int>());
sort(v.begin(),v.end(),greater<int>());
for(int i=0;i<v.size();i++) cout<<v[i];
for(vector<int>::iterator it=v.begin();it!=v.end();++it) cout<<*it;
for(auto it=v.begin();it!=v.end();++it) cout<<*it;
for(auto x:v) cout<<x;
stack
stack<int> s;
s.push(7);
s.top();
s.pop();
s.size();
s.empty();
进制转换(十进制转二进制)
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;
}
逆序单词
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;
}
queue、priority_queue、deque
queue<int> q;
q.push(7);
q.front();
q.back();
q.pop();
q.size();
q.empty();
清空队列:
q=queue<int>();
while(!q.empty()) q.pop();
void clear(queue<int>& q){
queue<int>empty;
swap(empty,q);
}
优先队列:
priority_queue<Type, Container, Functional>
Type数据类型,Container容器类型(数组实现——vector,deque等,但不能用list。STL默认vector),Functional比较方式
使用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆
priority_queue <int,vector<int>,greater<int> > q;
priority_queue <int,vector<int>,less<int> > q;
Priority_queue<node>q;
push( )
top( )
pop( )
size( )
empty( )
struct node{
int x,y;
node(){}
node(int a,int b):x(a),y(b) { }
operator <(const node &rhs)const{
if(x==rhs.x)
return y>rhs.y;
return x>rhs.x;
}
};
int main(){
priority_queue<node> q;
q.push(node(1,2)); ...... q.push(node(7,8));
while(!q.empty()){
node temp=q.top();
q.pop();
cout<<temp.x<<' '<<temp.y<<endl;
}
return 0;
}
合并果子——有n堆果子,两两合并直到只剩一堆,每次合并消耗为两堆重量之和,求最小消耗
int main(){
priority_queue<int,vector<int>,greater<int> > q;
int n,m,i,ans,p1,p2;
cin>>n;
for(int i=0;i<n;i++){
cin>>m;
q.push(m);
}
for(int i=0;i<n;i++){
p1=q.top(); q.pop();
p2=q.top(); q.pop();
ans+=p1+p2; q.push(p1+p2);
}
cout<<ans<<endl;
return 0;
}
deque(双端队列):可以从任一端添加或移除项;这种混合线性结构提供了单个数据结构中栈和队列的所有能力。
连续内存的容器不能随意扩充,但deque却可以,这是因为它创造了内存连续的假象(每次扩充申请一个新的内存段)。
deque的内存并不真的连续,只是分段连续,当走向段尾时自动跳到下一段内存,支持迭代器++操作(由operator++实现)
deque<int> d;
deque<int> d1(d);
deque<int> d2 = d1;
deque<int> d3 (5,6);
deque<int> d4(d3.begin()+2, d3.begin()+3);
deque<int> d5({2,3,4,5});
deque<int> d6 = {2,3,4,5};
push_back();
push_front();
pop_back();
pop_front();
empty();
max_size();
resize(10, 5);
insert(d.begin()+3, 7);
erase(d.begin()+3);
swap(d1);
clear();
emplace(d.end(), 7);
emplace_front(7);
emplace_back(7);
shrink_to_fit();
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>());
pair
STL<utility>的模板类pair,表示一个二元组或元素对,其中两个数据值的数据类型可以不同。
pair模板类对象有两个成员:first 和 second 分别表示首元素和尾元素。
#include<utility>
pair<string,double>p1;
pair<string,double>p2(“apple”,7.0);
pair<string,double>p3(p2)
pair<string,double>*p4=new pair<string,double>(“banana”,7.0);
若pair的使用比较繁琐,定义多个形同的pair类型的时候,可以时候typedef简化声明:
typedef pair<string,int>student;
student stu1(“Tom”,2019);
student stu2(“Jerry”,2020);
通过 first second 来访问:
pair<string,int>student(“Tom”,2019);
cout<<student.first<<' '<<student.second<<endl; 输出:Tom 2019
如需即时生成一个pair对象,除了直接定义还可以调用<utility>的模板函数——make_pair:
int main(){
typedef struct pair<string,int> stu;
stu stu1=make_pair("Tom",2019);
cout<<stu1.first<<' '<<stu1.second<<endl;
stu1.first="Jerry"; stu1.second=2020;
cout<<stu1.first<<' '<<stu1.second<<endl;
return 0;
}
输出:
Tom 2019
Jerry 2020
Pair 排序:
<utility>中已定义pair的六个比较运算符—— <、>、<=、>=、==、!=(first相等时再比较second)
typedef pair<int,int> P;
bool cmp(const P &a,const P&b){
if(a.first==b.first)
return a.second<b.second;
return a.first<b.first;
}
sort(st,st+n,cmp);
map
map(映射)内部自建红黑树,具有自动排序功能,所以map内的数据是有序的。
map自动建立key--value的对应,key和value可以是任意需要的类型
根据key的值快速查找记录(二分),复杂度为O(log2(N)),插入、删除同理
map<string,int>mapstring;
map<int,string>mapint;
map<string,char>mapstring;
map<char,string>mapchar;
map<char,int>mapchar;
map<int,char>mapint;
map<int,int> m;
m[1]=2; m[3]=4; m[5]=6;
mp.insert(pair<int,int>(7,8));
m.insert(map<int,int>::value_type(9,10));
for(auto 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(auto tmp:m)
cout<<tmp.first<<"->"<<tmp.second<<endl;
for(int i=1;i<=m.size();i++)
cout<<i<<": "<<m[i]<<endl;
↑遍历到m[2]会自动创建一个m[2]=0;,同理还会有m[4]=0;↑
m.size()一开始=3,之所以i能+到5是因为:
当i=2时执行完m[2]=0;后m.size()==>4,同理当i=4时执行完m[4]=0;后m.size()==>5
↓要想m.size()保持不变需要改成下面这样↓
for(int i=1;i<=5;i+=2)
cout<<i<<": "<<m[i]<<endl;
bool cmp(const pair<int,int> a, const pair<int,int> b){
return a.second>b.second;
}
int main(){
unordered_map<int,int> m;
m[1]=2; m[5]=6; m[3]=4;
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;
}
begin() 返回指向map头部的迭代器
end() 返回指向map末尾的迭代器
rbegin() 返回指向map尾部的逆向迭代器
rend() 返回指向map头部的逆向迭代器
size() 返回map中元素的个数
max_size() 返回可以容纳的最大元素个数
empty() 如果map为空则返回true
erase() 删除一个元素
Iterator erase(iterator it);
Iterator erase(iterator first,iterator last)
Iterator erase(iterator Key&key);
find() 返回key所在位置的迭代器,未找到返回end()
count() 判断指定key是否出现,返回值为0或1
insert() 插入元素
swap() 交换两个map
clear() <==> map.erase(map.begin(),map.end());
equal_range() 返回特殊条目的迭代器对
get_allocator() 返回map的配置器
lower_bound() 返回键值>=给定元素的第一个位置
upper_bound() 返回键值>给定元素的第一个位置
key_comp() 返回比较元素key的函数
value_comp() 返回比较元素value的函数
【小于号重载——】
typedef struct Student{
int id;
string name;
Student(int i,string n):id(i),name(n) { }
bool operator<(const Student &obj)const{
if(id==obj.id){
if(name==obj.name)
return false;
return name<obj.name;
}
return id<obj.id;
}
} stu,*pStu;
int main(){
map<stu,int> m;
m.insert(map<stu,int>::value_type(stu(1,"Tom"),97));
m.insert(map<stu,int>::value_type(stu(2,"Jerry"),99));
for(auto tmp:m)
cout<<'('<<tmp.first.id<<','<<tmp.first.name<<')'<<"->"<<tmp.second<<endl;
return 0;
}
【仿函数——】
typedef struct Student{
int id;
string name;
Student(int i,string n):id(i),name(n) { }
} stu,*pStu;
class sort{
public:
bool operator() (stu const &_A,stu const &_B)const{
if(_A.id == _B.id){
if(_A.name == _B.name)
return false;
return _A.name<_B.name;
}
return _A.id<_B.id;
}
};
int main(){
map<stu,int,sort> m;
m.insert(map<stu,int>::value_type(stu(1,"Tom"),97));
m.insert(map<stu,int>::value_type(stu(2,"Jerry"),99));
for(auto x:m)
cout<<'('<<x.first.id<<','<<x.first.name<<')'<<"->"<<x.second<<endl;
return 0;
}
set
set, multiset, map, multimap内部采用的都是红黑树(平衡检索二叉树)
set<int> s;
unordered_set<int> uns;
insert(key_value)
find(key_value)
erase(iterator)
erase(it1,it2)
erase(key_value)
begin()
end()
rbegin()
rend()
clear()
empty()
size()
max_size()
lower_bound(key_value)
upper_bound(key_value)
for(auto tmp:s)
cout<<tmp<<" ";
cout<<endl;
for(auto it=s.begin();it!=s.end();it++)
cout<<*it<<" ";
cout<<endl;
自定义比较函数——
(1)元素不是结构体:
struct myCmp{
bool operator()(const basic_type &a, const basic_type &b){
return a>b;
}
};
set<basic_type, myComp>s;
......
set<basic_type, myComp>::iterator it;
(2)如果元素是结构体,可以直接将比较函数写在结构体内:
struct Info{
string name;
float score;
bool operator < (const Info &a) const{
return score>a.score;
}
}
set<Info> s;
......
set<Info>::iterator it;
list
1. 如果你需要高效的随机存取,而不在乎插入和删除的效率,使用vector
2. 如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque
3. 如果你需要大量的插入和删除,而不关心随机存取,则应使用list
list(双向循环链表)——内存不连续,不支持快速随机存取([]和at),因此迭代器只能++或--,不能+n或-n。
list<int> li;
li.insert(++li.begin(),7);
li.insert(li.begin(),7,7);
li.insert(li.begin(),l2.begin(),l2.end());
li.emplace_front(8);
li.emplace_back(9);
li.erase(++li.begin());
li.erase(li.begin(),li.end());
li.splice(++li.begin(), li2);
li.assign(n, val)
li.assign(li2.begin(),li2.end())
li.merge(li2 ~~,默认greater<int>()可省略~~ );
li.swap(li2); || swap(li1,li2);
resize(n)
resize(n, val)
push_back()
push_front()
pop_back()
pop_front()
front()
back()
reverse()
unique()
remove()
remove_if()
for(auto tmp:li) cout<<tmp<<endl;
for(auto it=li.begin();it!=li.end();it++) cout<<*it<<endl;