java 中缀表达式转后缀表达式

lz在网上百度啦理论知识然后自己实现了代码,有些网友的代码实在。。。。好吧,我们开始

1 基本概念

在计算机中表达式有三种,前缀表达式(波兰式),中缀表达式,后缀表达式(逆波兰式)。

如表达式:a+b*(c-d)-e/f

前缀表达式:-+a*b-cd/ef

中缀表达式:a+b*(c-d)-e/f

后缀表达式:abcd-*+ef/-

1.1 特点与利弊

中缀表达式的括号必不可少,它的优点是符合我们人类的书写和读取习惯,但缺点是它不方便计算机处理。

前缀和后缀表达式的缺点是不是我们阅读的习惯,但是它们却便于计算机的处理。比如针对后缀表达式来说,它是把操作数一直压入栈中,然后遇到一个操作符的时候,就从栈中取出两个数进行计算,再把得到的结果压入栈中。因此前缀和后缀是非常方便计算机处理的。

现在考虑把中缀表达式转化为后缀表达式或者是从输入的中缀表达式转换为后缀表达式。

2 转换原理

原理不难,我们遇到遇到操作数的时候直接输出,当遇到操作符(包括‘(’,‘+’,‘-’,‘*’,‘/’)的时候,我们需要把符号压入到栈中,

2.1 当遇到‘)’的时候:

我们需要依次从栈顶弹出符号,直到遇到‘(’,并且要将‘(’弹出。如:(a*(b+c)),栈中的是(*(+,当遇到‘)’的时候,我们要弹出‘+’,‘(’。

2.2 当遇到‘(’的时候

此时没什么要说的,直接压栈。

2.3 当遇到‘+’,‘-’,‘*’,‘/’的时候:

我们要把栈顶元素的符号的优先级跟输入的符号的优先级进行对比,如果栈顶优先级高的话,我们就要把栈顶元素依次弹出,直到栈顶的优先级低于输入的优先级或者栈空。

如:a+b+c+d,跟a+b*c+d得到的符号顺序就不一样,原因就是这个优先级的问题。

2.4 当遇到操作数的时候:
毫无疑问,直接输出
以上从http://www.2cto.com/kf/201409/335701.html摘抄,毫无疑问,非常清晰:)

以下为lz代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class InfixToPostfix {
    //定义入栈结构体
    private static class Operator {
        char oper;   //操作符
        int degree;  //优先级
        Operator(char oper, int degree) {
            this.degree = degree;
            this.oper = oper;
        }
    }
    private static String convertExpr(String infix) {
        StringBuffer postfix = new StringBuffer();
        Stack<Operator> s = new Stack<Operator>(); //申请一个栈用来存放操作符
        int n = infix.length();
        for (int i = 0; i < n; i++) {  //逐个遍历每一个字符
            char c = infix.charAt(i);
//          当遇到‘)’的时候我们需要依次从栈顶弹出符号,直到遇到‘(’,并且要将‘(’弹出。
            if (c == ')') {
                while (!s.isEmpty()&&s.peek().oper != '(') {
                    postfix.append(s.peek().oper);
                    s.pop();
                }
                s.pop();   //将‘(‘弹出
            }
//          直接压栈
            else if (c == '(') {
                Operator operator  = new Operator(c, 0);
                s.push(operator);
            }
//          
            else if (c == '-'||c == '+') {
                Operator operator  = new Operator(c, 1);
                    while (!s.isEmpty()&&operator.degree <= s.peek().degree) {
                        postfix.append(s.peek().oper);
                        s.pop();
                    }
                    s.push(operator);
            }
            else if (c == '*'||c == '/') {
                Operator operator  = new Operator(c, 2);
                    while (!s.isEmpty()&&operator.degree <= s.peek().degree) {
                        postfix.append(s.peek().oper);
                        s.pop();
                    }
                    s.push(operator);
            }
            else {
                postfix.append(c);
            }
        }
//      遍历完后将栈中所有元素抛出
        while (!s.isEmpty()) {
            postfix.append(s.peek().oper);
            s.pop();
        }
        return postfix.toString();
    }
    public static void main(String[] args) {
        String infix = null;
        System.out.println("Please enter Infix expression:");
//      读取中缀表达式
        BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
        try {
            infix = buf.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

//      输出后缀表达式
        System.out.println("The Postfix is :\n"+convertExpr(infix));

    }
}

亲测可用“`
大家发现bug或想扩展请留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值