中序表达式转换为逆波兰表达式

中序表达式转换为逆波兰表达式,实现了基本的加减乘除以及括号的应用。


将一个普通的中序 表达式 转换为 逆波兰表达式 的一般算法是:
首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆 波兰 式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:
(1)若取出的字符是 操作数 ,则分析出完整的运算数,该操作数直接送入S2栈
(2)若取出的字符是 运算符 ,则将该运算符与S1栈栈顶元素比较,如果该 运算符优先级 大于S1栈栈顶 运算符 优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。
(3)若取出的字符是“(”,则直接送入S1栈栈顶。
(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个 出栈 ,依次送入S2栈,此时抛弃“(”。
(5)重复上面的1~4步,直至处理完所有的输入字符
(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个 出栈 ,依次送入S2栈。
完成以上步骤,S2栈便为逆 波兰 式输出结果。不过S2应做一下逆序处理。便可以按照逆 波兰 式的计算方法计算了!


#include<iostream>
using namespace std;
#define MaxSize 100
#define MaxOp 7
struct{
    char ch;
    int pri;
}
lpri[] = {{'=',0},{'(',1},{'*',5},{'/',5},{'+',3},{'-',3},{')',6}},
rpri[] = {{'=',0},{'(',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}};
int leftpri(char op){
    int i;
    for(i=0;i<MaxOp;i++)
        if(lpri[i].ch == op)
            return lpri[i].pri;
}
int rightpri(char op){
    int i;
    for(i=0;i<MaxOp;i++)
        if(rpri[i].ch == op)
            return rpri[i].pri;
}
int InOp(char ch){
    if(ch == '(' || ch == ')' ||ch == '+' || ch == '-' || ch == '*' || ch == '/')
        return 1;
    else
        return 0;
}
int Precede(char op1,char op2){
    if(leftpri(op1) == rightpri(op2))
        return 0;
    else if(leftpri(op1) < rightpri(op2))
        return -1;
    else
        return 1;
}
void trans(char * exp,char postexp[]){
    struct{
        char data[MaxSize];
        int top;
    }op;
    int i=0;
    op.top=-1;
    op.top++;
    op.data[op.top]='=';
    while(* exp != '\0'){
        if(!InOp(* exp)){
            while(* exp >= '0' && * exp <= '9'){
                postexp[i++] = * exp;
                exp++;
                if(* exp == '.'){
                    postexp[i++] = * exp;
                    exp++;
                }
            }
            postexp[i++]='#';
        }
        else{
            switch(Precede(op.data[op.top],* exp)){
                case -1:
                    op.top++;
                    op.data[op.top] = * exp;
                    exp++;
                    break;
                case 0:
                    op.top--;
                    exp++;
                    break;
                case 1:
                    postexp[i++] = op.data[op.top];
                    op.top--;
                    break;
            }
        }
    }
    while(op.data[op.top] != '='){
        postexp[i++] = op.data[op.top];
        op.top--;
    }
    postexp[i] = '\0';
}
float calculated(char * postexp){
    struct{
        float data[MaxSize];
        int top;
    }st;
    float d,a,b,c,e,f;
    st.top=-1;
    while(* postexp != '\0'){
        switch(* postexp){
            case '+':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=a+b;
                st.top++;
                st.data[st.top]=c;
                break;
            case '-':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=b-a;
                st.top++;
                st.data[st.top]=c;
                break;
            case '*':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=a*b;
                st.top++;
                st.data[st.top]=c;
                break;
            case '/':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                if(a != 0){
                    c=b/a;
                    st.top++;
                    st.data[st.top]=c;
                }else{
                    cout<<"除零错误!"<<endl;
                    exit(0);
                }
                break;
            default:
                d=0;
                e=0;
                f=0;
                while(* postexp >= '0' && * postexp <= '9'){
                    d=10 * d+ *postexp-'0';
                    postexp++;
                    if(* postexp == '.'){
                        postexp++;
                        while(* postexp >= '0' && * postexp <= '9'){
                            f++;
                            e=e * 10 + *postexp-'0';
                            postexp++;
                        }
                        for(int i=0;i<f;i++)
                            e=e/10;
                    }
                }
                d=d+e;
                st.top++;
                st.data[st.top]=d;
                break;
        }
        postexp++;
    }
    return st.data[st.top];
}
int main(){
    char exp[MaxSize];
    char postexp[MaxSize];
    float value = 0;
    cout<<"请输入你要计算的式子:";
    cin>>exp;
    trans(exp,postexp);
    cout<<"转换成后缀表达式为:"<<postexp<<endl;
    value = calculated(postexp);
    cout<<"计算结果为:"<<value<<endl;
    return 0;
}


本文出自 “淡定的dreamer” 博客,请务必保留此出处http://idiotxl1020.blog.51cto.com/6419277/1288623

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值