目录
用法3:二分查找(lower_bound、upper_bound)
用法4:全排列(next_permutation、prev_permutation)
--------------------------------------------end--------------------------------------------
一、实用语法
1.重载运算符
众所周知,结构体是一个我们编程中非常常用的工具,但它有一个比较大的缺陷:不能直接进行操作。比如说,我们想把两个结构体相加,那肯定是不能直接做到的。更常见的情况是排序,如果使用sort对结构体排序,一般必须使用cmp。但c++为我们提供了一个解决方法:运算符重载
格式如下:
返回类型 operator 运算符名称(形参列表){
重载实体;
}
注:结构体内外都可以定义,但结构体外定义需要多加一个形参:const 结构体类型名称& 结构体类型变量名,如:const node& a
单纯看这个可能看不懂,下边来看一组示例:
#include<iostream>
using namespace std;
struct node{
int x,y;
node operator + (const node& tmp){
node res;
res.x=x+tmp.x;
res.y=y+tmp.y;
return res;
}
};
int main(){
node a{1,2},b{3,4};
node ans=a+b;
cout<<ans.x<<" "<<ans.y<<endl;
return 0;
}
输出:
4 6
运算符重载更常用的范围是排序:
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int x,y;
bool operator < (const node& t){
if(x==t.x){
return y<t.y;
}
return x<t.x;
}
}r[12];
int main(){
for(int i=1;i<=10;i++){
cin>>r[i].x>>r[i].y;
}
sort(r+1,r+10);
for(int i=1;i<=10;i++){
cout<<r[i].x<<" "<<r[i].y<<endl;
}
return 0;
}
输入:
1 2
5 2
4 5
2 8
1 3
1 5
1 4
2 9
3 4
5 4
输出:
1 2
1 3
1 4
1 5
2 8
2 9
3 4
4 5
5 2
5 4
2.随机数生成
常用于竞赛中的对拍。
①rand()
范围:1~32767
使用方法:
取范围[n,m]的数,写法为 rand()%(m-n+1)+n
#include<iostream>
#include<ctime>
using namespace std;
int main(){
srand(unsigned(time(0)));
int count1=rand()%3+1; //范围:1~3
int count2=rand()%3; //范围:0~2
cout<<count1<<endl<<count2;
return 0;
}
②mt19937()
范围:无限制,可自己设定
使用方法:
无限制:
#include<iostream>
#include<chrono>
#include<random>
using namespace std;
int main(){
//随机数种子
unsigned seed=std::chrono::system_clock::now().time_since_epoch().count();
mt19937 rand_num(seed); //大随机数
cout<<rand_num()<<endl;
return 0;
}
手动设定范围:
#include<iostream>
#include<chrono>
#include<random>
using namespace std;
int main(){
//随机数种子
unsigned seed=std::chrono::system_clock::now().time_since_epoch().count();
mt19937 rand_num(seed); //大随机数
uniform_int_distribution<long long> dist(0,1000000);//给定范围:0~1000000
cout<<dist(rand_num)<<endl;
return 0;
}
可以看出,mt19937()使用起来非常麻烦,因此建议用多个rand()函数的结果相乘,也可以生成较大的随机数,且使用起来非常简便。
二、STL库函数
1.algorithm
头文件:<algorithm>
用法1:排序(sort)
默认从小到大排序,如有其他需要可自行添加比较函数(cmp)
例(从大到小):
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,7,4};
bool cmp(int a,int b){
return a>b;
}
int main(){
sort(a,a+6,cmp);
for(int i=0;i<6;i++){
cout<<a[i]<<" ";
}
return 0;
}
输出:
7 5 4 3 2 1
用法2:去重(unique)
可以将有序数据中的重复元素去除
例:
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
sort(a,a+6);
int len=unique(a,a+6)-a;
cout<<len<<endl;
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
return 0;
}
输出:
4
1 2 3 5
用法3:二分查找(lower_bound、upper_bound)
二分查找有序数据中的元素
例:
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
/*
二分查找num的位置
lower_bound是查找第一个大于等于num的位置
upper_bound是查找第一个大于num的位置,如果不存在就返回最后一个元素的后一位
*/
sort(a,a+6);
int num=3;
int x=lower_bound(a,a+6,num)-a;
int y=upper_bound(a,a+6,num)-a;
cout<<x<<" "<<y;
return 0;
}
输出:
3 4
用法4:全排列(next_permutation、prev_permutation)
将有序数据进行全排列
例:
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
/*
next_permutation:求下一个全排列
*/
sort(a,a+6);
do{
for(int i=0;i<6;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}while(next_permutation(a,a+6));
return 0;
}
输出:
1 2 2 3 5 5
1 2 2 5 3 5
1 2 2 5 5 3
1 2 3 2 5 5
1 2 3 5 2 5
1 2 3 5 5 2
1 2 5 2 3 5
1 2 5 2 5 3
1 2 5 3 2 5
1 2 5 3 5 2
1 2 5 5 2 3
1 2 5 5 3 2
1 3 2 2 5 5
1 3 2 5 2 5
1 3 2 5 5 2
1 3 5 2 2 5
1 3 5 2 5 2
1 3 5 5 2 2
1 5 2 2 3 5
1 5 2 2 5 3
1 5 2 3 2 5
1 5 2 3 5 2
1 5 2 5 2 3
1 5 2 5 3 2
1 5 3 2 2 5
1 5 3 2 5 2
1 5 3 5 2 2
1 5 5 2 2 3
1 5 5 2 3 2
1 5 5 3 2 2
2 1 2 3 5 5
2 1 2 5 3 5
2 1 2 5 5 3
2 1 3 2 5 5
2 1 3 5 2 5
2 1 3 5 5 2
2 1 5 2 3 5
2 1 5 2 5 3
2 1 5 3 2 5
2 1 5 3 5 2
2 1 5 5 2 3
2 1 5 5 3 2
2 2 1 3 5 5
2 2 1 5 3 5
2 2 1 5 5 3
2 2 3 1 5 5
2 2 3 5 1 5
2 2 3 5 5 1
2 2 5 1 3 5
2 2 5 1 5 3
2 2 5 3 1 5
2 2 5 3 5 1
2 2 5 5 1 3
2 2 5 5 3 1
2 3 1 2 5 5
2 3 1 5 2 5
2 3 1 5 5 2
2 3 2 1 5 5
2 3 2 5 1 5
2 3 2 5 5 1
2 3 5 1 2 5
2 3 5 1 5 2
2 3 5 2 1 5
2 3 5 2 5 1
2 3 5 5 1 2
2 3 5 5 2 1
2 5 1 2 3 5
2 5 1 2 5 3
2 5 1 3 2 5
2 5 1 3 5 2
2 5 1 5 2 3
2 5 1 5 3 2
2 5 2 1 3 5
2 5 2 1 5 3
2 5 2 3 1 5
2 5 2 3 5 1
2 5 2 5 1 3
2 5 2 5 3 1
2 5 3 1 2 5
2 5 3 1 5 2
2 5 3 2 1 5
2 5 3 2 5 1
2 5 3 5 1 2
2 5 3 5 2 1
2 5 5 1 2 3
2 5 5 1 3 2
2 5 5 2 1 3
2 5 5 2 3 1
2 5 5 3 1 2
2 5 5 3 2 1
3 1 2 2 5 5
3 1 2 5 2 5
3 1 2 5 5 2
3 1 5 2 2 5
3 1 5 2 5 2
3 1 5 5 2 2
3 2 1 2 5 5
3 2 1 5 2 5
3 2 1 5 5 2
3 2 2 1 5 5
3 2 2 5 1 5
3 2 2 5 5 1
3 2 5 1 2 5
3 2 5 1 5 2
3 2 5 2 1 5
3 2 5 2 5 1
3 2 5 5 1 2
3 2 5 5 2 1
3 5 1 2 2 5
3 5 1 2 5 2
3 5 1 5 2 2
3 5 2 1 2 5
3 5 2 1 5 2
3 5 2 2 1 5
3 5 2 2 5 1
3 5 2 5 1 2
3 5 2 5 2 1
3 5 5 1 2 2
3 5 5 2 1 2
3 5 5 2 2 1
5 1 2 2 3 5
5 1 2 2 5 3
5 1 2 3 2 5
5 1 2 3 5 2
5 1 2 5 2 3
5 1 2 5 3 2
5 1 3 2 2 5
5 1 3 2 5 2
5 1 3 5 2 2
5 1 5 2 2 3
5 1 5 2 3 2
5 1 5 3 2 2
5 2 1 2 3 5
5 2 1 2 5 3
5 2 1 3 2 5
5 2 1 3 5 2
5 2 1 5 2 3
5 2 1 5 3 2
5 2 2 1 3 5
5 2 2 1 5 3
5 2 2 3 1 5
5 2 2 3 5 1
5 2 2 5 1 3
5 2 2 5 3 1
5 2 3 1 2 5
5 2 3 1 5 2
5 2 3 2 1 5
5 2 3 2 5 1
5 2 3 5 1 2
5 2 3 5 2 1
5 2 5 1 2 3
5 2 5 1 3 2
5 2 5 2 1 3
5 2 5 2 3 1
5 2 5 3 1 2
5 2 5 3 2 1
5 3 1 2 2 5
5 3 1 2 5 2
5 3 1 5 2 2
5 3 2 1 2 5
5 3 2 1 5 2
5 3 2 2 1 5
5 3 2 2 5 1
5 3 2 5 1 2
5 3 2 5 2 1
5 3 5 1 2 2
5 3 5 2 1 2
5 3 5 2 2 1
5 5 1 2 2 3
5 5 1 2 3 2
5 5 1 3 2 2
5 5 2 1 2 3
5 5 2 1 3 2
5 5 2 2 1 3
5 5 2 2 3 1
5 5 2 3 1 2
5 5 2 3 2 1
5 5 3 1 2 2
5 5 3 2 1 2
5 5 3 2 2 1
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
bool cmp(int a,int b){
return a>b;
}
int main(){
/*
prev_permutation:求上一个全排列
*/
sort(a,a+6,cmp);
do{
for(int i=0;i<6;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}while(prev_permutation(a,a+6));
return 0;
}
输出:
5 5 3 2 2 1
5 5 3 2 1 2
5 5 3 1 2 2
5 5 2 3 2 1
5 5 2 3 1 2
5 5 2 2 3 1
5 5 2 2 1 3
5 5 2 1 3 2
5 5 2 1 2 3
5 5 1 3 2 2
5 5 1 2 3 2
5 5 1 2 2 3
5 3 5 2 2 1
5 3 5 2 1 2
5 3 5 1 2 2
5 3 2 5 2 1
5 3 2 5 1 2
5 3 2 2 5 1
5 3 2 2 1 5
5 3 2 1 5 2
5 3 2 1 2 5
5 3 1 5 2 2
5 3 1 2 5 2
5 3 1 2 2 5
5 2 5 3 2 1
5 2 5 3 1 2
5 2 5 2 3 1
5 2 5 2 1 3
5 2 5 1 3 2
5 2 5 1 2 3
5 2 3 5 2 1
5 2 3 5 1 2
5 2 3 2 5 1
5 2 3 2 1 5
5 2 3 1 5 2
5 2 3 1 2 5
5 2 2 5 3 1
5 2 2 5 1 3
5 2 2 3 5 1
5 2 2 3 1 5
5 2 2 1 5 3
5 2 2 1 3 5
5 2 1 5 3 2
5 2 1 5 2 3
5 2 1 3 5 2
5 2 1 3 2 5
5 2 1 2 5 3
5 2 1 2 3 5
5 1 5 3 2 2
5 1 5 2 3 2
5 1 5 2 2 3
5 1 3 5 2 2
5 1 3 2 5 2
5 1 3 2 2 5
5 1 2 5 3 2
5 1 2 5 2 3
5 1 2 3 5 2
5 1 2 3 2 5
5 1 2 2 5 3
5 1 2 2 3 5
3 5 5 2 2 1
3 5 5 2 1 2
3 5 5 1 2 2
3 5 2 5 2 1
3 5 2 5 1 2
3 5 2 2 5 1
3 5 2 2 1 5
3 5 2 1 5 2
3 5 2 1 2 5
3 5 1 5 2 2
3 5 1 2 5 2
3 5 1 2 2 5
3 2 5 5 2 1
3 2 5 5 1 2
3 2 5 2 5 1
3 2 5 2 1 5
3 2 5 1 5 2
3 2 5 1 2 5
3 2 2 5 5 1
3 2 2 5 1 5
3 2 2 1 5 5
3 2 1 5 5 2
3 2 1 5 2 5
3 2 1 2 5 5
3 1 5 5 2 2
3 1 5 2 5 2
3 1 5 2 2 5
3 1 2 5 5 2
3 1 2 5 2 5
3 1 2 2 5 5
2 5 5 3 2 1
2 5 5 3 1 2
2 5 5 2 3 1
2 5 5 2 1 3
2 5 5 1 3 2
2 5 5 1 2 3
2 5 3 5 2 1
2 5 3 5 1 2
2 5 3 2 5 1
2 5 3 2 1 5
2 5 3 1 5 2
2 5 3 1 2 5
2 5 2 5 3 1
2 5 2 5 1 3
2 5 2 3 5 1
2 5 2 3 1 5
2 5 2 1 5 3
2 5 2 1 3 5
2 5 1 5 3 2
2 5 1 5 2 3
2 5 1 3 5 2
2 5 1 3 2 5
2 5 1 2 5 3
2 5 1 2 3 5
2 3 5 5 2 1
2 3 5 5 1 2
2 3 5 2 5 1
2 3 5 2 1 5
2 3 5 1 5 2
2 3 5 1 2 5
2 3 2 5 5 1
2 3 2 5 1 5
2 3 2 1 5 5
2 3 1 5 5 2
2 3 1 5 2 5
2 3 1 2 5 5
2 2 5 5 3 1
2 2 5 5 1 3
2 2 5 3 5 1
2 2 5 3 1 5
2 2 5 1 5 3
2 2 5 1 3 5
2 2 3 5 5 1
2 2 3 5 1 5
2 2 3 1 5 5
2 2 1 5 5 3
2 2 1 5 3 5
2 2 1 3 5 5
2 1 5 5 3 2
2 1 5 5 2 3
2 1 5 3 5 2
2 1 5 3 2 5
2 1 5 2 5 3
2 1 5 2 3 5
2 1 3 5 5 2
2 1 3 5 2 5
2 1 3 2 5 5
2 1 2 5 5 3
2 1 2 5 3 5
2 1 2 3 5 5
1 5 5 3 2 2
1 5 5 2 3 2
1 5 5 2 2 3
1 5 3 5 2 2
1 5 3 2 5 2
1 5 3 2 2 5
1 5 2 5 3 2
1 5 2 5 2 3
1 5 2 3 5 2
1 5 2 3 2 5
1 5 2 2 5 3
1 5 2 2 3 5
1 3 5 5 2 2
1 3 5 2 5 2
1 3 5 2 2 5
1 3 2 5 5 2
1 3 2 5 2 5
1 3 2 2 5 5
1 2 5 5 3 2
1 2 5 5 2 3
1 2 5 3 5 2
1 2 5 3 2 5
1 2 5 2 5 3
1 2 5 2 3 5
1 2 3 5 5 2
1 2 3 5 2 5
1 2 3 2 5 5
1 2 2 5 5 3
1 2 2 5 3 5
1 2 2 3 5 5
用法 5:最大、最小(max、min)
查找最大、最小
例:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
/*
max(a,b)查找a和b的最大值
min(a,b)查找a和b的最小值
*/
int a=1,b=2;
cout<<max(a,b)<<endl;
cout<<min(a,b);
return 0;
}
输出:
2
1
用法6:交换(swap)
交换两个变量的值。
例:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
/*
swap(a,b)交换a和b的值
*/
int a=1,b=2;
swap(a,b);
cout<<a<<" "<<b;
return 0;
}
用法7:查找(find)
查找一个元素的位置。
例:
#include<iostream>
#include<algorithm>
using namespace std;
int a[]={3,1,4,1,7,9};
int main(){
/*
find(begin,end,value);
返回区间中第一个元素值等于 value 的元素位置。
find_if(begin,end,op);
返回区间中第一个满足“op(elem)==true”的元素位置。
如果没有找到匹配元素,则返回所传入的 end,不是 NULL!
*/
int ans=find(a,a+6,7)-a;
cout<<ans;
return 0;
}
输出:
4
2.stack(栈)
头文件<stack>
stack(栈)是 STL 实现的栈容器,可以实现栈的基本操作
以下所有操作时间复杂度为O(1)
stack<int> stk; | 常用函数功能 |
stk.push(x); | 将x入栈 |
stk.top(); | 获取栈顶元素 |
stk.pop(); | 弹出栈顶元素 |
stk.empty(); | 判断栈是否为空 空返回true,不空返回false |
stk.size(); | 返回栈内元素个数 |
括号匹配
时间限制:1秒 内存限制:128M
题目描述
假设表达式中允许包含圆括号和方括号两种括号,其嵌套的顺序随意,如([]())或[([][])]等为正确的匹配,[(])或([]()或(()))均为错误的匹配
本题的任务是检验一个给定的表达式中的括号是否匹配正确
输入一个只包含圆括号和方括号的字符串,判断字符串中的括号是否匹配,匹配就输出“OK”,不匹配就输出“Wrong”
输入描述
一行字符,只含有圆括号和方括号,个数小于255
输出描述
匹配就输出一行文本“OK“,不匹配就输出一行文本”Wrong”
样例
输入
[(])
输出
Wrong
#include<iostream>
#include<stack>
using namespace std;
stack<char> stk;
bool check(string s){
stk.push('#');
for(int i=0;i<s.size();i++){
char c=s[i];
if(c==')'){
if(stk.top()=='('){
stk.pop();
}
else{
return false;
}
}
else if(c==']'){
if(stk.top()=='['){
stk.pop();
}
else{
return false;
}
}
else{
stk.push(c);
}
}
return stk.size()==1;
}
int main(){
string s;
cin>>s;
if(check(s)){
cout<<"OK";
}
else{
cout<<"Wrong";
}
return 0;
}
3.queue(队列)
头文件<queue>
queue(队列)是 STL 实现的队列容器,可以实现队列的基本操作
以下所有操作时间复杂度为O(1)
queue<int> q; | 常用函数操作 |
q.push(x); | 将x入队 |
q.front(),q.back() | front()返回队首,back()返回队尾 |
q.pop(); | 队首元素出队 |
q.empty(); | 判断队是否为空 空返回true,不空返回false |
q.size(); | 返回队内元素个数 |
priority_queue(优先队列)
头文件<queue>
优先队列,底层实现是堆,可将压入队内的元素自动排序
定义方法:
priority_queue<int>q; //默认降序优先队列
priority_queue<int, vector<int>, greater<int> >q; //升序优先队列
priority_queue<int, vector<int>, less<int> >q; //降序优先队列
priority_queue<int> q; | 常用函数操作 |
q.push(x); | 将x入队 |
q.top(); | 返回队首元素 |
q.pop(); | 队首元素出队 |
q.empty(); | 判断队是否为空 空返回true,不空返回false |
q.size(); | 返回队内元素个数 |
可插入运算符重载后的结构体或pair
deque(双端队列)
头文件<deque>
双端队列,队列两端都可以出队或入队
deque<int> q; | 常用函数操作 |
q.push_front(x); | 将x从队首入队 |
q.push_back(x); | 将x从队尾入队 |
q.front(); | 返回队首元素 |
q.back(); | 返回队尾元素 |
q.pop_front(); | 队首元素出队 |
q.pop_back(); | 队尾元素出队 |
q.empty(); | 判断队是否为空 空返回true,不空返回false |
q.size(); | 返回队内元素个数 |
周末舞会
时间限制:1秒 内存限制:128M
题目描述
假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。现要求写一个程序,模拟上述舞伴配对问题。(0<m,n,k<1000)
输入描述
第一行男士人数m和女士人数n;
第二行舞曲的数目k。输出描述
共k行,每行两个数,表示配对舞伴的序号,男士在前,女士在后。
样例
输入
2 4 6输出
1 1 2 2 1 3 2 4 1 1 2 2提示
显然,舞伴配对的顺序符合“先进先出”,所以用两个队列分别存放男士队伍和女士队伍,然后模拟k次配对:每次取各队队头元素“配对”输出,并进行“出队”和重新“入队”的操作
#include<iostream>
#include<queue>
using namespace std;
int main(){
int n,m,k;
cin>>n>>m>>k;
queue<int> q1,q2;
for(int i=1;i<=n;i++){
q1.push(i);
}
for(int i=1;i<=m;i++){
q2.push(i);
}
for(int i=1;i<=k;i++){
cout<<q1.front()<<" "<<q2.front()<<endl;
q1.push(q1.front());
q1.pop();
q2.push(q2.front());
q2.pop();
}
return 0;
}
合并果子
时间限制:1秒 内存限制:128M
题目描述
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。 因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。 例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
输入描述
输入包括两行,第一行是一个整数n(1< =n< =10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1< =ai< =20000)是第i种果子的数目。
输出描述
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。
样例
输入
3 1 2 9输出
15提示
对于30%的数据,保证有n< =1000: 对于50%的数据,保证有n< =5000; 对于全部的数据,保证有n< =10000。
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int n,x,ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;
q.push(x);
}
while(q.size()>=2){
int a=q.top();
q.pop();
int b=q.top();
q.pop();
ans+=(a+b);
q.push(a+b);
}
cout<<ans;
return 0;
}
4.vector(向量)
头文件<vector>
本质是一个动态大小的数组,可存放任意类型的对象。
操作及时间复杂度:
vector<int> a(10); | 定义了 10 个整型元素的向量 (尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的 | O(n) |
vector<int> a(10,1); | 定义了 10 个整型元素的向量,且元素的初值都为 1 | O(n) |
vector<int> a(b); | 用 b 向量来创建 a 向量,整体复制性赋值 | O(n) |
vector<int>a(b.begin(),b.begin+3); | a 的初值为向量 b 的前三个值 | O(n) |
int b[7]={1,2,3,4,5,9,8}; vector<int> a(b,b+7); | 从数组中获得初值 | O(n) |
v[i]; | 以下标方式访问元素 | O(1) |
v.push_back(x); | 往尾部插入元素 x (常用) | O(1) |
v.insert(it, x); | 向迭代器 it 指向的位置插入 x,原位置后移 | O(n) |
v.size(); | 返回表长,注意是 unsigned 类型 | O(1) |
v.front(); | 取首元素的值 | O(1) |
v.back(); | 取尾元素的值 | O(1) |
v.empty(); | 表为空返回true,否则返回false | O(1) |
v.clear(); | 清空表 | O(1) |
v.pop_back(); | 删除表尾元素 | O(1) |
v.erase(it); | 删除迭代器 it 指向的元素 | O(n) |
vector迭代器
类似于指针,用于访问元素
例:
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++){ //begin()表示首元素位置,end()表尾元素位置
cout<<*it<<endl;
}
5.map(映射)
头文件<map>
可以简单理解为下标可以是任何类型的数组,可用于解释函数
操作:
m.find(x) | 查找x是否存在 |
m.count(x) | 键为 x 的数量(等同于查找 x 是否存在) |
m.empty() | 判断是否为空 |
m.size() | 返回容器内元素数量 |
m.insert(x) | 插入x,x 必须为对的形式。 可以为 pair 的形式,通过 make_pair 创建。 |
m.erase(x) | 将键值为 x 的元素删除。 |
m.clear() | 清空 map |
map 的底层是红黑树,所以查找、插入、删除、访问的时间复杂度都是 log 级。
map迭代器
与vector迭代器类似,有以下区别:
- map是有序的,根据第一关键字自动排序
- map迭代器取值不用*,而用 ->first 取第一关键字, ->second 取第二关键字
- map 的迭代器只能++,--,不能+-数值
unordered_map
头文件<unordered_map>
与map几乎完全一样,区别在于unordered_map是无序的,其操作速度比map稍快一点。
multimap
头文件<map>
同样与map几乎完全一样,但可以保存重复元素。
查字典
时间限制:1秒 内存限制:128M
题目描述
全国英语四级考试就这样如期到来了,可是小Y依然没有做好充分的准备。为了能够大学毕业,可怜的小Y决定作弊。(太胆大妄为了,不怕被学校开除!!)
小Y费尽心机,在考试的时候夹带了一本字典进考场。但是现在的问题是,考试的时候可能有很多单词要查,小Y能不能来得及呢。
输入描述
第一行一个整数N,表示字典中一共有多少单词(N<=10000)。
接下来每两行表示一个单词,其中: 第一行是一个长度<=100的字符串,表示这个单词,全部小写字母,单词不会重复。
第二行是一个整数,表示这个单词在字典中的页码。
接下来一行是一个整数M,表示要查的单词数(M<=10000)。
接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。
输出描述
M行,每行一个整数,表示第i个单词在字典中的页数。
样例
输入
2 scan 10 word 15 2 scan word输出
10 15
#include<iostream>
#include<map>
using namespace std;
int main(){
map<string,int> m;
int n;
cin>>n;
string t;
for(int i=0;i<n;i++){
cin>>t;
cin>>m[t];
}
cin>>n;
for(int i=0;i<n;i++){
cin>>t;
cout<<m[t]<<endl;
}
return 0;
}
6.set(集合)
头文件<set>
去重,可以自动升序排序
set<T> s; | 常用函数操作 |
s.insert(x); | 插入x |
s.erase(x); | 删除x |
s.count(x); | 查找x,存在返回1,不存在返回0 |
s.clear(); | 清空 |
unordered_set
头文件<unordered_set>
和set类似,去重但无序。
multiset
头文件<set>
和set类似,有序但不去重。
集合的并
时间限制:1秒 内存限制:128M
题目描述
现在有两个集合,计算两个集合的并,即{A}+{B}。
注:{A}+{B}中不允许出现重复元素,但是{A}与{B}之间可能存在相同元素。
输入描述
多组测试数据。
每组数据包含三行。
第一行为两个正整数n,m。分别表示两个集合的元素数量。
第二行为第一个集合元素、第三行为第二个集合元素。
输出描述
输出两个集合并后的元素。
样例
输入
1 2 1 2 3 1 2 1 1 2输出
1 2 3 1 2提示
A集合与B集合内部元素可能会出现重复。
n,m不超过10000.
集合内元素最大不超过int的最大值。
#include<iostream>
#include<set>
using namespace std;
set<int> se;
int main(){
int n,m,x;
while(cin>>n>>m){
se.clear();
for(int i=1;i<=n;i++){
cin>>x;
se.insert(x);
}
for(int i=1;i<=m;i++){
cin>>x;
se.insert(x);
}
while((int)se.size()){
cout<<*se.begin()<<" ";
se.erase(se.begin());
}
cout<<endl;
}
return 0;
}
7.memset(填充)
头文件<cstring>
格式:memset(数组名,值,sizeof(数组名));
作用:将数组全部赋值。
注意:建议赋值时只赋值0,-1,0x3f.
8.pair(对)
包含两个数据值,两数据类型可不同。
初始化:pair<类型1,类型2> 名称
可在定义时直接赋值,如pair<string,string> a("CS","DN");x
用法:第一个元素为a.first,第二个元素为b.second.
用已有的两个元素生成pair,可用make_pair(),如make_pair(1,"CSDN");
9.万能头文件
#include<bits/stdc++.h>
一个几乎万能的头文件,包含所有可用到的C++库函数。
优点:
节约时间,减少工作量。
缺点:
增加编译时间,个别在线评测系统不兼容。
--------------------------------------------end--------------------------------------------
ps:后续还可能会不断完善,感谢支持!