D. DS栈—波兰式,逆波兰式(dsoj c++)

题目描述

       表达式有三种表示方法,分别为:

    前缀表示(波兰式):运算符+操作数1+操作数2

    中缀表示:操作数1+运算符+操作数2

    后缀表示(逆波兰式):操作数1+操作数2+运算符

    例如:a +b * (c -d ) - e/f

    波兰式:-+a*b-cd/ef     (运算符在操作数的前面,用递归计算波兰式)

    中缀式:a+b*c-d-e/f  

    逆波兰式:abcd-*+ef/-   (运算符在操作数的后面,用栈计算逆波兰式)

       中缀表示就是原表达式去掉扣号。       

     根据表达式求波兰式、逆波兰式都是教材第三章表达式求值的思想。     

      求波兰式,需要操作数栈(注意不是计算结果入栈,有计算式入栈),运算符栈。区别在于从后往前扫描表达式,‘(’ 换成')','('换成‘)’。栈顶运算符优先级>新读入运算符优先级出栈,教材第三章表3.1中的相同运算符优先级>(从左往右计算)改为<,例如栈顶为‘+‘,新读入的为‘+’,则栈顶优先级<新读入的优先级。

     求逆波兰式,只需要运算符栈。操作数直接输出,操作符按表3.1优先级顺序出栈,输出。

       输入表达式,求其波兰式和逆波兰式。

输入

 测试次数

每组测试数据一行,一个合法表达式

输出

 对每组测试数据,输出两行

第一行,表达式的波兰表示

第二行,表达式的逆波兰表示

不同组测试数据间以空行分隔。

输入样例1 :

2
4+2*3-10/5
12+3*5+(2+10)*5 

输出样例1:

- + 4 * 2 3 / 10 5
4 2 3 * + 10 5 / -

+ + 12 * 3 5 * + 2 10 5
12 3 5 * + 2 10 + 5 * +

#include <iostream>
#include <stack>
#include <cstring>
//#include<vector>
using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        //前缀(波兰式)从右往左读入
        stack<char>sw; //存放操作符
        string st; //输入的中缀计算式
        string an[1000]; //存输出
        cin >> st;
        int k=0;
        int len= st.length();
        for (int i = len-1; i>=0; i--)
        {
            if (st[i] >= '0'&&st[i]<='9') //如果是数字则直接存进输出
            {
                string temp = "";
                temp = st[i] + temp;
                -- i;
                while(st[i]>= '0'&&st[i]<= '9') //如果前一个还是数字,则继续进temp里
                {
                    temp = st[i] + temp;
                   --i;
                }
                ++i;
                an[k]=temp;
                k++;
                continue;
            }
            
            if (st[i] == '(') //碰上左括号说明括号里内容输完了
            {
                
                while (sw.top() != ')') //将操作符弹出进输出数组里
                {
                    an[k]=sw.top();
                    k++;
                    sw.pop();
                }
                sw.pop();
            }
            else
            {
                if (st[i] == ')') //如果碰上右括号就压栈
                {
                    sw.push(st[i]);
                }
                //如果是+-*/的操作符,就按序比较
                while (st[i] == '+' || st[i] == '-' || st[i] == '*' || st[i] == '/')
                {
                    if (sw.empty()) //如果栈是空的,则无需比较,直接压栈
                    {
                        sw.push(st[i]);
                        break;
                    }
                    //如果栈不为空,则将当前操作符与栈顶操作符比较优先级,如果低于栈顶操作符,则进输出数组
                    if (((st[i] == '+' && (sw.top() == '/' || sw.top() == '*' )) || (st[i] == '-' && (sw.top() == '*'  || sw.top() == '/')) ))
                    {
                            an[k]=sw.top();
                            k++;
                            sw.pop();
                    }
                    //否则,则进栈
                    else
                    {
                        sw.push(st[i]);
                        break;
                    }
                }
            }

        }
        while (!sw.empty()) //将栈中的操作符传入输出数组
        {
            an[k]=sw.top();
            k++;
            sw.pop();
        }
        for (int i = k - 1; i >= 0; --i) //输出
        {
            cout << an[i];
            if (i) cout << ' ';
            else puts("");
        }
       //后缀(逆波兰式)从左往右读 思路与前缀相似
        stack<char>s;
        string str;
        string ans[1000];
        //vector<char> ans;
        str = st;
        k=0;
        len= str.length();
        for (int i = 0; i < len; i++)
        {
            if (str[i] >= '0'&&str[i]<='9')
            {
                int temp=str[i]-'0';
                int j=i+1;
                while(str[j]>= '0'&&str[j]<= '9')
                {
                    temp=temp*10+(str[j]-'0');
                    j++;
                }
                i=j-1;
                ans[k]=to_string(temp);
                k++;
            }
            
            if (str[i] == ')')
            {
                
                while (s.top() != '(')
                {
                    ans[k]=s.top();
                    k++;
                    s.pop();
                }
                if (s.top() == '(')
                {
                    s.pop();
                }
            }
            else
            {
                if (str[i] == '(')
                {
                    s.push(str[i]);
                }
                while (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
                {
                    if ((s.empty()) || (s.top() == '(') || ((str[i] == '*' && (s.top() == '/' || s.top() == '+' || s.top() == '-')) || (str[i] == '/' && (s.top() == '*' || s.top() == '+' || s.top() == '-')) || (str[i] == '+' && (s.top() == '-')) || (str[i] == '-' && (s.top() == '+'))))
                    {
                        s.push(str[i]);
                        break;
                    }
                    else
                    {
                        while (!s.empty())
                        {
                            ans[k]=s.top();
                            k++;
                            s.pop();
                        }
                    }
                }
            }

        }
        while (!s.empty())
        {
            ans[k]=s.top();
            k++;
            s.pop();
        }
        for (int i = 0; i < k; i++)
        {
            cout << ans[i];
            if (i != k - 1) cout << ' ';
            
        }
        if (t){
            puts("");
            puts("");
        }
    }
}

本次题目谢谢chc和zhw的帮助哈哈哈哈哈哈!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值