逆波兰表达式的生成(Java版)

逆波兰表达式的生成(Java版)

逆波兰表达式又叫做后缀表达式。

正常表达逆波兰表达
a+ba,b,+
a+(b-c)a,b,c,-,+

网上很多的转换逆波兰表达式的代码都使用了太多了for, if, 还有各种char之间的比较,读起来非常的累人。
在逆波兰表达式中比较麻烦的一步就是比较各个运算符之间的优先级关系

() > */ > +-
括号 (大于) 乘除 (大于) 加减
网上的很多方法是通过判断字符的ASCII码来判断运算符的优先级。
对应的ASCII码表如下:
+ 43
- 45
* 42
/ 47
( 40
) 41
可以看出除法的ASCII码值是47,但是他的优先级确又高过加法和减法。
因此我们创建一个内部类,来定义每个操作符的优先级。

/**
     * 内部类
     * content包含具体的字符信息
     * priority 定义了运算符的优先级
     */
    private static class Element{
        private Character content;
        private int priority;

        public Element() {
        }

        public Character getContent() {
            return content;
        }

        public void setContent(Character content) {
            this.content = content;
        }

        public int getPriority() {
            return priority;
        }

        public void setPriority(int priority) {
            this.priority = priority;
        }

        @Override
        public String toString() {
            return content + " ";
        }
    }

对于具体的逆波兰表达式的生成的核心代码如下
定义好一个存放最终表达式结果的List,以及一个存放操作符和左右括号的栈(Stack)

    //读到的是操作符(+-*/)(记为read),将其与栈顶的操作符(记为top)进行优先级比较:
    // 如果read>top,read入栈,继续读下一个;read≤top,top出栈,并输出到list中,read继续和新的top比较;
    // top为空,read直接入栈;若top是“(”,read直接入栈,因为“(”优先级最高;
    private void processOperator(Element read, List<Element> list, Stack<Element> operations){
        if(operations.isEmpty()){
            operations.push(read);
            return;
        }
        Element tmp = operations.peek();
        if(read.getPriority()>tmp.getPriority()){
            operations.push(read);
        }else{
            list.add(operations.pop());
            processOperator(read, list, operations);
        }
    }

完整代码如下

package java_data_structure;


import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 参考 http://blog.csdn.net/bruce_6/article/details/39205837
 *
 * @author Junying Li
 */
public class ReversePolishExpression {

    /**
     * 内部类
     * content包含具体的字符信息
     * priority 定义了运算符的优先级
     */
    private static class Element{
        private Character content;
        private int priority;

        public Element() {
        }

        public Character getContent() {
            return content;
        }

        public void setContent(Character content) {
            this.content = content;
        }

        public int getPriority() {
            return priority;
        }

        public void setPriority(int priority) {
            this.priority = priority;
        }

        @Override
        public String toString() {
            return content + " ";
        }
    }

    public static void main(String[] args){
        //[6 , 5 , 2 , 3 , + , 8 , * , + , 3 , + , * ]
        String expression = "6*(5+(2+3)*8+3)";
//        String expression = "a+(b-c)*d";
        ReversePolishExpression instance = new ReversePolishExpression();
        List<Element> result = instance.convertExpressionToReversePolish(expression);
        System.out.print(result);
    }

   public List<Element> convertExpressionToReversePolish(String expression){
       //将字符串表达式转换成一个List,定义好其中的算术表达符的优先级
       List<Element> preparedElementsList = prepareElementsList(expression.toCharArray());

       List<Element> resultList = new ArrayList<>();
       Stack<Element> operatorStack = new Stack<>();
       for(Element e : preparedElementsList){
           Character c = e.getContent();
           switch (c){
               case '+':
                   processOperator(e, resultList, operatorStack);
                   break;
               case '-':
                   processOperator(e, resultList, operatorStack);
                   break;
               case '*':
                   processOperator(e, resultList, operatorStack);
                   break;
               case '/':
                   processOperator(e, resultList, operatorStack);
                   break;
               case '(':
                   operatorStack.push(e);
                   break;
               case ')':
                   for(int i=0; i<operatorStack.size(); i++){
                       Element x = operatorStack.peek();
                       if(x.getContent()!='('){
                           resultList.add(operatorStack.pop());
                       }else {
                           operatorStack.pop();
                           break;
                       }
                   }
                   break;
               default:
                   resultList.add(e);
           }
       }
       while (!operatorStack.isEmpty()){
           resultList.add(operatorStack.pop());
       }

       return resultList;
   }

    //
    private List<Element> prepareElementsList(char[] chars){
        List<Element> list = new ArrayList<>();
        for(char c : chars){
            Element element = new Element();
            element.setContent(c);
            if(c == '+' || c == '-'){
                element.setPriority(1);
            }else  if(c == '*' || c == '/'){
                element.setPriority(2);
            }
            list.add(element);
        }
        return list;
    }

    //读到的是操作符(+-*/)(记为read),将其与栈顶的操作符(记为top)进行优先级比较:
    //read>top,read入栈,继续读下一个;read≤top,top出栈,并输出到list中,
    // read继续和新的top比较;top为空,read直接入栈;若top是“(”,read直接入栈,因为“(”优先级最高;
    private void processOperator(Element read, List<Element> list, Stack<Element> operations){
        if(operations.isEmpty()){
            operations.push(read);
            return;
        }
        Element tmp = operations.peek();
        if(read.getPriority()>tmp.getPriority()){
            operations.push(read);
        }else{
            list.add(operations.pop());
            processOperator(read, list, operations);
        }
    }



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值