4.从中缀向后缀转换表达式

问题描述
  中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在编译程序对我们书写的程序中的表达式进行语法检查时,往往就可以通过逆波兰表达式进行。我们所要设计并实现的程序就是将中缀表示的算术表达式转换成后缀表示,例如,将中缀表达式
(A 一 (B*C 十 D)*E) / (F 十 G )
转换为后缀表示为:
ABC*D十E*–FG十/
注意:为了简化编程实现,假定变量名均为单个字母,运算符只有+,-,*,/ 和^(指数运算),可以处理圆括号(),并假定输入的算术表达式正确。
要求:使用栈数据结构实现 ,输入的中缀表达式以#号结束
输入
整数N。表示下面有N个中缀表达式
N个由单个字母和运算符构成的表达式
输出
N个后缀表达式。

测试用例1:
输入:
1
(A-(B*C+D)*E)/(F+G)#
输出:
ABC*D+E*-FG+/
测试用例2:
输入:
2
a+b*c-d#
a-b*(c+d)#
输出:
abc*+d-
abcd+*-

代码

#include<iostream>
using namespace std;

struct Stack
{
    Stack*father, *son;
    int data;
};

void StackPush(Stack*&p, int &a)
{
    Stack*NewStack = new Stack();
    NewStack->data = a;
    p->son = NewStack;
    NewStack->father = p;
    p = p->son;
}

int StackPop(Stack*&p)
{
    return p->data;
}

int StackEmpty(Stack*&p)
{
    return p->data == 0 ? 1 : 0;
}

int main()
{
    int Times;
    scanf("%d", &Times);
    Stack *RPN_Stack = new Stack();
    RPN_Stack->data = '#';
    RPN_Stack->father = RPN_Stack->son = NULL;
    while (Times--)
    {
        int ch,op_top,isp,icp,p=0;
        char Str[105] = { '\0' };
        scanf("%s", Str);
        while (1)
        {
            ch = Str[p];
            if (ch == '#'&&RPN_Stack->data == '#')
                break;
            if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
            {
                printf("%c", ch);
                p++;
                continue;
            }
            else
            {
                op_top = StackPop(RPN_Stack);
                switch (op_top)
                {
                    case '#':isp = 0; break;
                    case '(':isp = 1; break;
                    case '^':isp = 6; break;
                    case '*':isp = 5; break;
                    case '/':isp = 5; break;
                    case ')':isp = 8; break;
                    case '+':isp = 3; break;
                    case '-':isp = 3; break;
                }
                switch (ch)
                {
                    case '#':icp = 0; break;
                    case '(':icp = 8; break;
                    case '^':icp = 7; break;
                    case '*':icp = 4; break;
                    case '/':icp = 4; break;
                    case ')':icp = 1; break;
                    case '+':icp = 2; break;
                    case '-':icp = 2; break;
                }
                if (icp > isp)
                {
                    StackPush(RPN_Stack, ch);
                    p++;
                    continue;
                }
                if (icp < isp)
                {
                    printf("%c", StackPop(RPN_Stack));
                    RPN_Stack = RPN_Stack->father;
                    delete RPN_Stack->son;
                    RPN_Stack->son = NULL;
                    continue;
                }
                if (icp == isp)
                {
                    if (RPN_Stack->data == '(')
                    {
                        RPN_Stack = RPN_Stack->father;
                        delete RPN_Stack->son;
                        RPN_Stack->son = NULL;
                        p++;
                        continue;
                    }
                    else
                    {
                        RPN_Stack = RPN_Stack->father;
                        delete RPN_Stack->son;
                        RPN_Stack->son = NULL;
                        if (RPN_Stack->data != '#')
                            continue;
                        else
                            break;
                    }
                }
            }
        }
        printf("\n");
    }
    //system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值