【C/C++】学习STL标准模板库 005 stack、queue、priority_queue容器适配器 快到碗里来(◕ᴗ◕✿)

概述

C++ STL提供容器适配器,它可以将不适用的序列式容器变得适用,使其满足特定场景的需求。C++ STL提供的容器适配器有3种:stack(栈)、queue(队列)和priority_queue(优先队列)。其中可以用stack作为适配器的容器有vector、deque、list,默认使用deque容器;可以使用queue作为适配器的容器有deque和list,默认使用dequerq;可以用priority_queue作为适配器的容器有vector和deque,默认使用vector容器。需要注意的是,容器适配器没有迭代器,因此访问元素的唯一方式是遍历容器,通过不断地移除访问过的元素,去访问下一个元素。

 使用stack容器适配器

stack是一个后进先出(Last In First Out, LIFO)的线性表,插入和删除元素都只能在表的一端进行。插入元素的一端称为栈顶,而另一端称为栈底。push(elem)添加元素入栈,pop()删除元素出栈

/**
 * Created By Liu Xianmeng On 2022/11/30
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    vector<int> v;
    for(int i=0; i<10; ++i) v.push_back(i);
    printf("v中的元素为:");
    for(int i=0; i<10; ++i) printf("%d ", v[i]);
    stack<int, vector<int>> stk(v); // 用v创建一个stack
    stk.push(100); // 在栈顶插入元素100
    printf("\nstk中的元素数量为:%d", stk.size());
    printf("\nstk中的元素为:");
    while(!stk.empty()){
        printf("%d ", stk.top()); // 取出栈顶元素
        stk.pop(); // 删除栈顶元素
    }
    /* [打印结果如下]
     * v中的元素为:0 1 2 3 4 5 6 7 8 9
     * stk中的元素数量为:11
     * stk中的元素为:100 9 8 7 6 5 4 3 2 1 0 
     */
    return 0;
}

 使用queue容器适配器

queue是一个先进先出(First In First Out,FIFO)的线性存储表,元素的插入只能在队尾,元素的删除只能在队首。

/**
 * Created By Liu Xianmeng On 2022/12/2
 * 【queue容器适配器】
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    srand(time(NULL));
    int x;
    queue<int> q;
    for (int i = 0; i < 10; ++i) {
        x = rand()%100;
        q.push(x); // 入队
    }
    printf("队列中元素的个数为:%d\n", q.size());
    printf("队列是否为空:%s\n", q.empty()?"YES":"NO");
    printf("队列中第一个元素为:%d\n", q.front());
    printf("队列中最后一个元素为:%d\n", q.back());
    printf("队列中元素遍历为:\n");
    while(!q.empty()){
        printf("%d ", q.front());
        q.pop();
    }
    printf("\n删除所有元素后队列中元素的个数为:%d", q.size());
    /*  【打印结果如下】
        队列中元素的个数为:10
        队列是否为空:NO
        队列中第一个元素为:29
        队列中最后一个元素为:62
        队列中元素遍历为:
        29 19 50 67 88 74 62 9 31 62 
        删除所有元素后队列中元素的个数为:0
     */
    return 0;
}

使用priority_queue容器适配器

  • priority_queue与queue一样,只能从队尾插入元素,从队首删除元素。与queue不同的是,priority_queue只能访问位于队首的元素。另外,priority_queue有一个特性,就是队列中最大的元素总是位于队首,因此遵循最高级先出(first in,largest out)的原则。换句话说,priority_queue里的元素相当于进行了降序排序(从队头到队尾)
  • 使用priority_queue需要【#include <queue>】

/**
 * Created By Liu Xianmeng On 2022/12/3
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    srand(time(NULL));
    int x;
    priority_queue<int> pq;
    // 装入10个随机数
    for (int i = 0; i < 10; ++i) {
        x = rand()%100;
        pq.push(x);
    }
    printf("pq当前元素个数为:%d\n", pq.size());
    printf("pq是否为空:%s\n", pq.empty()?"YES":"NO");
    printf("pq第一个元素为:%d\n", pq.top());
    pq.pop();
    printf("删除一个元素后,pq元素个数为:%d\n", pq.size());
    printf("pq元素遍历:\n");
    while(!pq.empty()){
        printf("%d ", pq.top());
        pq.pop();
    }
    printf("\npq是否为空:%s\n", pq.empty()?"YES":"NO");
    return 0;
    /* 【打印结果】
        pq当前元素个数为:10
        pq是否为空:NO
        pq第一个元素为:76
        删除一个元素后,pq元素个数为:9
        pq元素遍历:
        66 57 42 25 24 9 6 5 1 
        pq是否为空:YES
     */
}

 

  编程实践

问题 G: 括号序列

时间限制: 1.000 Sec  内存限制: 128 MB

题目描述

定义满足以下规则字符串为规则序列,否则不是规则序列:
1.空序列是规则序列;
2.如果S是规则序列,那么(S),[S],{S}和<S>也是规则序列;
3.如果A和B都是规则序列,那么AB也是规则序列。
例如,下面的字符串都是规则序列:
(),[],(()),([]),()[],()[()],{{}}<>,([]<>{{}}),<<{}>>
而以下几个则不是:
(,[,],)(,()),([(),<<,{(}),<{}>)
现在,给你一些由"("、")"、"["、"]"、"{"、"}"、"<"、">"构成的字符串,请判断该字符串是否为规则序列。

输入

第一行:一个正整数N(0<N≤10),表示测试数据组数;
接下来N行:每行一个括号序列,长度不超过L(0<L≤2*106)。

输出

共N行:对于每一个括号序列,判断其是否规则。符合规则输出YES,否则输出NO。

样例输入 Copy

2
{()}<<>>
{{{{{}}}}

样例输出 Copy

YES
NO

分析与题解

/**
 * Created By Liu Xianmeng On 2022/12/3
 * 【括号匹配】很明显,这个问题是典型的栈的应用的问题
 *  所以出于感情的自然流露 我选择用stack栈来解决
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    int N;
    scanf("%d", &N);
    getchar(); // 输入N之后换行了 用一个getchar()来接收没有用的'\n' 
               // 免得后面ch读取到了 这不是我们所希望的
    /*********** 循环输入N个字符 ***********/
    for(int i=1; i<=N; ++i){
        stack<char> stack;
        /*********** while循环读取括号字符 那while循环什么时候 结束呢?
         *********** 答:遇到'\n'的时候 就说明一连串的括号字符读取完毕 ***********/
        while (true){
            char ch = getchar(); // 读取括号字符
            if(ch == '\n'){ // 如果读取到的是'\n' 则判断栈是否为空 
                            // 如果为空则说明括号字符串符合条件(全部匹配成功)则打印结果、break、程序结束 
                            // 不为空则不符合条件(存在括号不匹配) 则打印结果、break、程序结束 
                if(stack.size() == 0){
                    printf("YES\n");
                } else{
                    printf("NO\n");
                }
                break;
            }
            /***** 如果读取到的字符不是换行符 则执行下面的代码 *****/
            if(stack.size() == 0){ // 如果此时栈为空 说明不需要与当前读取到的字符进行左右括号匹配 
                                   // 直接push压栈即可
                stack.push(ch);
            } else{ // 如果此时栈不为空 则需要将栈顶字符与当前读取到的字符进行左右括号匹配
                if(stack.top() == '{'){ // 如果匹配成功 则删除栈顶元素
                    if(ch == '}') stack.pop();
                    else stack.push(ch);
                } else if(stack.top() == '<'){  // 如果匹配成功 则删除栈顶元素
                    if(ch == '>') stack.pop();
                    else stack.push(ch);
                } else if(stack.top() == '['){  // 如果匹配成功 则删除栈顶元素
                    if(ch == ']') stack.pop(); 
                    else stack.push(ch);
                } else if(stack.top() == '('){  // 如果匹配成功 则删除栈顶元素
                    if(ch == ')') stack.pop();
                    else stack.push(ch);
                } else{ // 否则 将当前的字符也压入栈
                    stack.push(ch);
                }
            }
        }
    }
    return 0;
}

 

 感谢读取~ >.<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值