Loading

PTA笔记 堆栈模拟队列+求前缀表达式的值

基础实验 3-2.5 堆栈模拟队列 (25 分)

设已知有两个堆栈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()。

输入格式:

输入首先给出两个正整数N1和N2,表示堆栈S1和S2的最大容量。随后给出一系列的队列操作: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

解题思路:

用容量较小的作为s1,容量较大的作为s2,那么当加入操作时,如果s1满了,s2没满,直接error,如果s1满了,s2没满,那么把s1内元素出栈入栈s2,出队时,如果s2不为空,输出栈顶元素即可,如果s2为空,将s1内元素全部出栈入栈s2,再输出即可,如果s2和s1都空,直接error
#include <bits/stdc++.h>
using namespace std;
/*    freopen("k.in", "r", stdin);
    freopen("k.out", "w", stdout); */
//clock_t c1 = clock();
//std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e3 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int main()
{
    int n1, n2;
    cin >> n1 >> n2;
    string op;
    stack<int> a, b;
    while (cin >> op && op != "T")
    {
        // 默认n1<n2;
        if (n1 > n2)
            swap(n1, n2);
        if (op == "A")
        {
            int num;
            cin >> num;
            if (b.empty() && a.size() == n1)
            {
                while (!a.empty())
                {
                    b.push(a.top());
                    a.pop();
                }
            }
            if (a.size() == n1 && !b.empty())
                printf("ERROR:Full\n");
            else
                a.push(num);
        }
        else
        {
            if (a.size() + b.size() == 0)
                printf("ERROR:Empty\n");
            else
            {
                if (b.empty())
                    while (!a.empty())
                    {
                        b.push(a.top());
                        a.pop();
                    }
                printf("%d\n", b.top());
                b.pop();
            }
        }
    }
    return 0;
}

进阶实验 3-3.1 求前缀表达式的值 (25 分)

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式:

输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、/以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式:

输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。

输入样例:

+ + 2 * 3 - 7 4 / 8 4

输出样例:

13.0

解题思路

从右扫描字符串,注意可能有+12或者-12这种数字
#include <bits/stdc++.h>
using namespace std;
/*    freopen("k.in", "r", stdin);
    freopen("k.out", "w", stdout); */
//clock_t c1 = clock();
//std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e3 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
/* 和后缀表达式相似,从右往左扫描字符串 */
char a[2000][200];
int cnt = 0;
char temp[2000];
int main()
{
    stack<double> s;
    while (~scanf("%s", temp))
    {
        strcpy(a[++cnt], temp);
    }
    bool flag = true;
    per(i, 1, cnt)
    {
        if (isdigit(a[i][0]) || isdigit(a[i][1]))
        {
            double temp = atof(a[i]);
            s.push(temp);
        }
        else
        {
            if (s.size() < 2)
            {
                flag = false;
                break;
            }
            double t1 = s.top();
            s.pop();
            double t2 = s.top();
            s.pop();
            if (a[i][0] == '+')
                s.push(t1 + t2);
            else if (a[i][0] == '-')
                s.push(t1 - t2);
            else if (a[i][0] == '*')
                s.push(t1 * t2);
            else if (a[i][0] == '/')
            {
                if (fabs(t2) <= eps)
                {
                    flag = false;
                    break;
                }
                s.push(t1 / t2);
            }
        }
    }
    if (s.empty())
        flag = false;
    if (flag && s.size() == 1)
        printf("%.1f\n", s.top());
    else
        printf("ERROR\n");
    return 0;
}

posted @ 2019-09-19 21:47  GrayKido  阅读(664)  评论(0编辑  收藏  举报