zoukankan      html  css  js  c++  java
  • PTA-7-22 堆栈模拟队列

    本题考点:采用堆栈模拟队列

    设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。

    所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:

    • int IsFull(Stack S):判断堆栈S是否已满,返回1或0;
    • int IsEmpty (Stack S ):判断堆栈S是否为空,返回1或0;
    • void Push(Stack S, ElementType item ):将元素item压入堆栈S
    • ElementType Pop(Stack S ):删除并返回S的栈顶元素。

    实现队列的操作,即入队void AddQ(ElementType item)和出队ElementType DeleteQ()

    输入格式:

    输入首先给出两个正整数N1N2,表示堆栈S1S2的最大容量。随后给出一系列的队列操作:A item表示将item入列(这里假设item为整型数字);D表示出队操作;T表示输入结束。

    输出格式:

    对输入中的每个D操作,输出相应出队的数字,或者错误信息ERROR:Empty。如果入队操作无法执行,也需要输出ERROR:Full。每个输出占1行。

    输入样例:

    3 2
    A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T
    

    输出样例:

    ERROR:Full
    1
    ERROR:Full
    2
    3
    4
    7
    8
    ERROR:Empty   
    

    解题思路

    采用堆栈模拟队列,堆栈是 FILO,而队列是 FIFO,所以如果我们需要用堆栈模拟队列,至少 需要两个栈。

    第一个栈栈用来保存输入的值,而采用第二个栈栈来保存从较小的栈中移动过去的值,此时较大的栈顶部就是最先输入的值了。

    而在本题中,所给的两个栈的大小不一样,所以需要选定一个栈当作输入栈,一个栈作为输出栈。
    如果我们想尽可能保存多的值,我们需要将较小的栈作为输入栈,较大的栈作为输出栈,这是因为:如果把较大的栈作为输入栈的话,较小的栈无法缓冲从较大的栈中转移过来的值。

    在输入过程中,一共会遇到这么几种情况(这里假定较小的栈为 s1,较大的栈为 s2):

    情况分析

    A(输入):

    1. s1 没满,直接放入 s1
    2. s1 满了,s2 为空,先把 s1 中的值都暂存到 s2 中,再保存到 s1
    3. s1 满了, s2 非空,此时需要输出 ERROR:Full (这是因为如果 s1 满了,无论再怎么放入 s1 或者 s2 都会打乱输出的顺序 )

    D(输出):
    4. s2 非空,直接输出 s2.top()
    5. s1 非空, s2 为空, 那么将 s1 中的值放入 s2 中,然后输出 s2.top()
    6. s1s2 都为空,那么输出 ERROR:Empty

    代码实现

    完整的代码实现如下:

    /*
        Author: Veeupup
     */
    #include <iostream>
    #include <cstdio>
    #include <cstdint>
    #include <stack>
    using namespace std;
    
    int s1Size, s2Size;
    stack<int> s1; // 容量较小,作为输入栈
    stack<int> s2; // 容量较大,作为输出栈
    
    int main()
    {
        scanf("%d%d", &s1Size, &s2Size);
        getchar();
        if (s1Size > s2Size)
            swap(s1Size, s2Size); // 较小的为输入栈
        int s1Num = 0, s2Num = 0, tempNum;
        char next;
        while (scanf("%c", &next) != EOF)
        {
            if(next == ' ')
                continue;
            if (next == 'A')
            {
                scanf("%d", &tempNum);
                if (s1Num < s1Size)
                {   // s1 不满,s2 为空,直接放入 s1 中
                    s1.push(tempNum);
                    s1Num++;
                }
                else if (s1Num == s1Size && s2Num == 0)
                {   // s1 满,s2 空,将 s1 中都放入 s2 中,再放入 s1 中
                    while (!s1.empty())
                    {
                        s2.push(s1.top());
                        s1.pop();
                        s2Num++;
                        s1Num--;
                    }
                    s1.push(tempNum);
                    s1Num++;
                }
                else if (s1Num == s1Size && s2Num > 0)
                {   // s1 满,s2 不为空,输出错误
                    printf("ERROR:Full
    ");
                }
            }
            else if (next == 'D')
            {
                if (s2Num > 0)
                {
                    printf("%d
    ", s2.top());
                    s2.pop();
                    s2Num--;
                }
                else if (s1Num > 0 && s2Num == 0)
                {
                    while (!s1.empty())
                    {
                        s2.push(s1.top());
                        s2Num++;
                        s1Num--;
                        s1.pop();
                    }
                    printf("%d
    ", s2.top());
                    s2Num--;
                    s2.pop();
                }
                else if (s1Num == 0 && s2Num == 0)
                {
                    printf("ERROR:Empty
    ");
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    fmt命令
    wc命令
    grep命令
    head命令
    C/C++语法知识:typedef struct 用法详解
    邻接表无向图的介绍
    邻接矩阵无向图的介绍
    图的基本概念
    careercup-栈与队列 3.6
    careercup-栈与队列 3.5
  • 原文地址:https://www.cnblogs.com/veeupup/p/12628869.html
Copyright © 2011-2022 走看看