前缀表达式、中缀表达式、后缀表达式

来源:互联网 发布:js购物车思路 编辑:程序博客网 时间:2024/06/06 01:11

中缀表达式就是我们日常看到的数学表达式:比如(2+4)*2,对于人类来说很直观,但是对于计算机而言,这种表达式很不容易理解。于是就有了前缀表达式和后缀表达式。

前缀表达式

前缀表达式是指将操作符放在前面,然后再放置操作数,比如对前面表达式而言,前缀表达式为*、+、2、4、2;

后缀表达式

后缀表达式是指将先放操作数,然后再放操作符,比如对签名表达式而言,后缀表达式为2、4、+、2、*

可以总结出规律,前缀表达式和后缀表达式的操作符顺序是相反的,而操作数的顺序是相同的。

为什么计算机对后缀表达式(前缀)比较方便

我们看到前缀表达式中不存在诸如括号改变优先级的符号,事实上,通过前缀表达式和后缀表达式可以很容易构造一颗运算树,通过该运算树,可以使用递归的方式很方便计算表达式,比如该运算式构成的树为:

这里写图片描述
然后这里,只需要int leftVal = calculate(root.left);int rightVal = calculate(root.right);然后可以计算出root值。

前缀表达式转树

前缀表达式如何变成一颗运算树呢?
通过前缀表达式,从后向前遍历,当出现运算数时,将运算数变成Node对象压栈,当出现运算符时,弹出栈中前两个对象,然后再构成一颗子树,入栈。。看代码吧

package com.dacas.converter;import java.util.Stack;/** * Created by dave on 2016/4/6. */public class ConvertPrefixExpressionToTree implements IConverter {    @Override    public TreeNode convert(String expression) {        char[] chars = expression.toCharArray();        Stack<TreeNode> nodes = new Stack<>();        for(int i = chars.length-1;i>=0;i--){            TreeNode root = new TreeNode(chars[i]);            if(!isValid(chars[i])){                TreeNode top1 = nodes.pop();                TreeNode top2 = nodes.pop();                root.setLeftNode(top1);                root.setRightNode(top2);            }            nodes.push(root);        }        return nodes.size() == 1?nodes.pop():null;    }}

后缀表达式转树

后缀表达式和前缀表达式构造树的方式非常类似。只是这次从前向后遍历。具体看代码

package com.dacas.converter; /** * Created by dave on 2016/4/6. */import java.util.Stack;/** * 将后缀表达式转换成一个表达式树 */public class ConvertPostExpressionToTree implements IConverter{    @Override    public TreeNode convert(String expression) {        Stack<TreeNode> nodes = new Stack<>();        char[] chars = expression.toCharArray();        for(char ch:chars){            TreeNode root = new TreeNode(ch);            if(!isValid(ch)) {                TreeNode top1 = nodes.pop();                TreeNode top2 = nodes.pop();                root.setLeftNode(top2);                root.setRightNode(top1);            }            nodes.push(root);        }        return nodes.size() == 1?nodes.pop():null;    }}

中缀表达式转后缀表达式

  1. 使用两个栈,一个是操作符栈,一个是操作数栈;
  2. 遍历中缀表达式,当一个字符为操作数时,压入操作数栈;当为操作码时,如果操作码栈为空,直接压入,如果为(,直接压入操作码栈,如果字符为),则出栈到(位置处,当操作码栈不为空时,比较栈顶元素与当前元素的优先级,如果当前元素优先级小于等于栈顶元素,则出栈,否则入栈。
package com.dacas.converter;import java.util.HashMap;import java.util.Map;import java.util.Stack;/** * Created by dave on 2016/4/6. * 将中缀表达式转换成后缀表达式 */public class ConvertMiddleExpressionToPostExpression{    static Map<Character,Integer> maps = new HashMap<>();    static {        maps.put('(',0);        maps.put('+',1);        maps.put('-',1);        maps.put('*',2);        maps.put('/',2);    }    public String convert(String midExpression){        Stack<Character> operators = new Stack<>();//操作符        Stack<String> operands = new Stack<>();//操作数        char[] chars = midExpression.toCharArray();        for(char ch:chars){            if(ch>='0' && ch<='9'){                operands.push(ch+"");            }else if(ch == '(') {                operators.push(ch);            }else if(ch == ')'){                char top;                while((top = operators.pop())!='('){                    String ch1 = operands.pop();                    String ch2 = operands.pop();                    operands.push(ch2 + "," + ch1 + "," + top);                }            }else{//操作符                while (!operators.isEmpty() && comparePriority(operators.peek(), ch)) {//top >= ch,pop out                    String ch1 = operands.pop();                    String ch2 = operands.pop();                    operands.push(ch2 + "," + ch1 + "," + operators.pop());                }                operators.push(ch);            }        }        while(!operators.isEmpty()){            String ch1 = operands.pop();            String ch2 = operands.pop();            operands.push(ch2+","+ch1+","+operators.pop());        }        return operands.pop();    }    private boolean comparePriority(char ch1,char ch2){        int int1 = maps.get(ch1);        int int2 = maps.get(ch2);        return int1 >= int2;    }}
Main.javaimport com.dacas.converter.*;/** * Created by dave on 2016/4/6. *///数据结构与算法分析第4章public class Main {    public static void main(String[] args) {        performConvertPostExpressionToTree();    }    private static void performConvertPostExpressionToTree(){        /***********后缀表达式转树***********/        String postfix = "ab+cde+**";        IConverter postConverter = new ConvertPostExpressionToTree();        TreeNode postNode = postConverter.convert(postfix);        System.out.println(postNode);        /************前缀表达式转树*****************/        String prefix = "-*+3456";        IConverter preConverter = new ConvertPrefixExpressionToTree();        TreeNode preNode = preConverter.convert(prefix);        System.out.println(preNode);        /****************中缀表达式转后缀表达式**********************/        String midfix = "3*(4+5/2-2*3/8)/2";        ConvertMiddleExpressionToPostExpression midConverter = new ConvertMiddleExpressionToPostExpression();        String postfixExpression = midConverter.convert(midfix);        System.out.println(postfixExpression);        String[] strs = postfixExpression.split(",");        String newString = "";        for(String tmp:strs){            newString+=tmp+"";        }        TreeNode postNode2 = postConverter.convert(newString);        System.out.println(postNode2);    }}
0 0