C++ STL(标准模板库)


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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢nn

心动不如行动,感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值