1.sort
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp1(int x,int y)
{
return x>y;
}
bool cmp2(int x,int y)
{
if(abs(x-50)<abs(y-50))
return true;
else
return false;
}
int main()
{
int arr[5]={3,2,-1,99,54};
sort(arr,arr+5);//顺序,默认
for(int i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
sort(arr,arr+5,cmp1);//逆序
for(int i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
sort(arr,arr+5,cmp2);//谁更接近50谁在前,注意:sort函数要比较任意两个元素之间的顺序
for(int i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
运行结果:
-1 2 3 54 99
99 54 3 2 -1
54 3 2 99 -1
多重排序:
#include<iostream>
#include<algorithm>
using namespace std;
struct student
{
string name;
int age;
}ss[100];
bool cmp(student a,student b)
{
if(a.age!=b.age) return a.age<b.age;
return a.name<b.name;
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ss[i].name>>ss[i].age;
}
sort(ss,ss+n,cmp);
for(int i=0;i<n;i++) cout<<ss[i].age<<" "<<ss[i].name<<endl;
return 0;
}
测试样例:
输入:
5
dasda 5
hgfh 4
bnvnv 6
rwer 4
dasdb 5
输出:
4 hgfh
4 rwer
5 dasda
5 dasdb
6 bnvnv
补充结构体排序:重载运算符
2.map
map:默认按升序排列
unordered_map:乱序
#include<iostream>
#include<map>
using namespace std;
map<int,int> mp;
int main()
{
//读入, 两种方法
for(int i=1;i<=10;i++)
{
mp[i]=i+1;
}
for(int i=10;i>=1;i--)
{
mp.insert(make_pair(i,i+1));
}
//删除
mp.erase(1);
mp.erase(mp.begin());
//遍历
map<int,int>::iterator i;
for(i=mp.begin();i!=mp.end();i++)
{
cout<<i->first<<" "<<i->second<<endl;//first对应键, second对应值
}
//查找,两种方法
cout<<mp.count(4)<<endl;//返回键1出现的次数,只有0次或1次
i=mp.find(5);//返回键为2的迭代器,当查找不到该键时,指向最后一个键值
if(i!=mp.end()) cout<<i->first<<" "<<i->second<<endl;
//清空
mp.clear();
//判断是否为空
if(mp.empty()) cout<<"容器已空"<<endl;
return 0;
}
3.stack
#include<iostream>
#include<string.h>
#include<stack>
using namespace std;
int main()
{
int n;
int flag=1;
char s[10010];
stack<char> q;
scanf("%d",&n);
while(n--)
{
flag=0;
scanf("%s",s);
for(int i=0;i<strlen(s);i++)
{
if(s[i]=='['||s[i]=='(') q.push(s[i]);
else
{
if(q.empty()) break;
}
if(s[i]==']')
{
if(q.top()!='[') break;
else q.pop();
}
if(s[i]==')')
{
if(q.top()!='(') break;
else q.pop();
}
}
if(q.empty()) flag=1;
if(flag) printf("Yes\n");
else printf("No\n");
while(!q.empty()) q.pop();
}
return 0;
}
表达式求值
题目描述:
给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。
测试样例:
输入:
(2+2)*(1+1)
输出:
8
代码如下:
#include <iostream>
#include <algorithm>
#include <stack>
#include <unordered_map>
using namespace std;
stack<int> num;
stack<char> op;
void eval()//算
{
auto b = num.top();
num.pop();
auto a = num.top();
num.pop();
auto c = op.top();
op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
int main()
{
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};//优先级
string str;
cin >> str;
for (int i = 0; i < str.size(); i ++ )
{
auto c = str[i];
if (isdigit(c))//判断是否为数字
{
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))//这个数可能有好多位
x = x * 10 + str[j ++ ] - '0';
i = j - 1;
num.push(x);
}
else if (c == '(') op.push(c);
else if (c == ')')
{
while (op.top() != '(') eval();
op.pop();//‘(’出栈,之后栈顶元素为‘(’之前的最后一个运算符
}
else
{
while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();//若当前运算符优先级较小时,子树遍历完成,需进行计算
op.push(c);
}
}
while (op.size()) eval();
cout << num.top() << endl;
return 0;
}
4.queue
q.empty() 如果队列为空返回true,否则返回false
q.size() 返回队列中元素的个数
q.pop() 删除队列首元素但不返回其值
q.front() 返回队首元素的值,但不删除该元素
q.push() 在队尾压入新元素
q.back() 返回队列尾元素的值,但不删除该元素
q.swap(p) 将当前 queue 中的元素和参数 queue 中的元素交换。
5.deque
6. priority_queue
#include<iostream>
#include<queue>
using namespace std;
deque<int> d;
int main()
{
priority_queue<int> q1;//默认为降序
for(int i=0;i<10;i++)
{
q1.push(rand());
}
while(!q1.empty())
{
cout<<q1.top()<<endl;
q1.pop();
}
cout<<endl;
priority_queue<int,vector<int>,greater<int> > q2;//升序
for(int i=0;i<10;i++)
{
q2.push(rand());
}
while(!q2.empty())
{
cout<<q2.top()<<endl;
q2.pop();
}
return 0;
}
7.pair
默认对first排序,当first相同时,对second排序
用sort对pair进行排序
#include<iostream>
#include<algorithm>
using namespace std;
pair<int,int> p[100];
int cmp(pair<int,int>a,pair<int,int>b)
{
return a.first<b.first;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d %d",&a,&b);
p[i]=make_pair(a,b);
}
sort(p,p+n,cmp);
for(int i=0;i<n;i++)
{
printf("%d %d\n",p[i].first,p[i].second);
}
return 0;
}
8.vector
reserve与resize的用法:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v1,v2;
v1.resize(10,5);//设置大小,可以指定初始值
v2.reserve(15);//设置容量,不可以指定初始值
cout<<v1.size()<<endl;
for(int i=0;i<10;i++) cout<<v1[i]<<" ";
cout<<endl;
cout<<v2.size()<<endl;
for(int i=0;i<15;i++) cout<<v2[i]<<" ";
return 0;
}
天梯:7-89 分而治之
#include<iostream>
#include<vector>
using namespace std;
int n,m,k;
int s1[10010],s2[10010];
void check()
{
int flag=1;
for(int i=1;i<=n;i++)
{
if(s2[i]>0)//有相邻的点
{
flag=0;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
int main()
{
cin>>n>>m;
vector<vector<int>> v(n+1);//vector存图
while(m--)
{
int a,b;
cin>>a>>b;
v[a].push_back(b);//a指向b
v[b].push_back(a);
s1[a]++;
s1[b]++;
}
cin>>k;
while(k--)
{
int l;
cin>>l;
for(int i=1;i<=n;i++)
{
s2[i]=s1[i];
}
for(int i=0;i<l;i++)
{
int a;
cin>>a;
s2[a]=0;
for(int j=0;j<v[a].size();j++)
{
s2[v[a][j]]--;//核心代码
}
}
check();
}
return 0;
}
9.set
概念
set就是集合,STL的set用平衡二叉树实现,集合中的每个元素只出现一次,并且是默认按键值升序排列
multiset中每个元素可以出现多次
unordered_set 乱序
set<int> q; //定义一个int类型的集合,默认按键值升序
set<int,greater<int>> q;//降序排列
int x;
q.insert(x); //将x插入q中
q.erase(x); //删除q中的x元素,返回0或1,0表示q中不存在x元素
q.clear(); //清空
q.empty(); //判断q是否为空,若为空则返回1,否则返回0
q.size(); //返回q中元素的个数
q.count();
q.find(x); //在q中查找x,返回x的迭代器,若x不存在,则返回指向q尾部的迭代器即 q.end()
q.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素
q.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素
q.rend(); //返回第一个元素的的前一个元素迭代器
q.begin(); //返回指向q中第一个元素的迭代器
q.end(); //返回指向q最后一个元素下一个位置的迭代器
q.rbegin(); //返回最后一个元素
基本操作
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> q;
//去重
q.insert(5);
q.insert(5);
q.insert(5);
cout<<q.size()<<endl;
//清空
q.clear();
cout<<q.size()<<endl;
//遍历+自动排序
q.insert(3);
q.insert(1);
q.insert(4);
q.insert(2);
set<int>::iterator i;
for(i=q.begin();i!=q.end();i++) cout<<*i<<" ";
cout<<endl;
//删除
q.erase(4);
for(i=q.begin();i!=q.end();i++) cout<<*i<<" ";
cout<<endl;
//降序排列
set<int,greater<int>> p;
p.insert(3);
p.insert(1);
p.insert(4);
p.insert(2);
for(i=p.begin();i!=p.end();i++) cout<<*i<<" ";
cout<<endl;
return 0;
}
set存储多元素
#include<iostream>
#include<set>
using namespace std;
struct node{
int a,b;
bool operator< (const node W)const
{
return a<W.a;//按a升序排列
}
}t;
int main()
{
set<node> q;
t.a=3;
t.b=5;
q.insert(t);
t.a=2;
t.b=4;
q.insert(t);
t.a=5;
t.b=1;
q.insert(t);
set<node>::iterator i;
for(i=q.begin();i!=q.end();i++)
{
t=*i;
cout<<t.a<<" "<<t.b<<endl;
}
return 0;
}
列车调度
//把set用到极致
#include<iostream>
#include<set>
using namespace std;
int main()
{
int n;
cin>>n;
set<int> s;
s.insert(0);
for(int i=0;i<n;i++)
{
int a;
cin>>a;
if(a<*s.rbegin())//如果a小于集合中的最大值
{
s.erase(*(s.upper_bound(a)));//删除第一个比a大的元素
}
s.insert(a);
}
cout<<s.size()-1;
return 0;
}