表达式求值

来源:互联网 发布:淘宝男鞋排行榜 编辑:程序博客网 时间:2024/06/05 03:07

1. 后序(逆波兰)

对形如 ABC*+ 的后序表达式进行求值,所有操作数均为 0 - 9 的整数,操作符包含 +、-、*、/ ,其中 +、- 均为二元操作符

import java.util.Stack;/** * 后序表达式求值 */public class PostfixSolution {    private Stack<Integer> result = new Stack<>();    private void calculate(char operator) {        int right = result.pop();        int left = result.pop();        switch (operator) {            case '+':                result.push(left + right);                break;            case '-':                result.push(left - right);                break;            case '*':                result.push(left * right);                break;            case '/':                result.push(left / right);                break;            default:                System.exit(1);                break;        }    }    public int solve(String postfix) {        char[] array = postfix.toCharArray();        for (int i = 0; i < array.length; i++) {            if (Character.isDigit(array[i])) {                result.push(array[i] - '0');            } else {                calculate(array[i]);            }        }        return result.pop();    }    public static void main(String[] args) {        System.out.println(new PostfixSolution().solve("32+"));    }}

2. 中序

中序表达式求值一般可以分为两步,

  • 中序表达式转后序
  • 后序求值

两步合并为一步操作如下:

import java.util.Stack;/** * 中缀表达式(含括号)求值 */public class InfixSolution {    private static Stack<Integer> result = new Stack<>();    private static Stack<Character> operator = new Stack<>();    private static void calculate(char operator) {        int right = result.pop();        int left = result.pop();        switch (operator) {            case '+':                result.push(left + right);                break;            case '-':                result.push(left - right);                break;            case '*':                result.push(left * right);                break;            case '/':                result.push(left / right);                break;            default:                System.exit(1);                break;        }    }    private static int getPriority(char operator) {        if (operator == '#') {            return 0;        } else if (operator == '('){            return 1;        } else if (operator == '+' || operator == '-') {            return 2;        } else if (operator == '*' || operator == '/') {            return 3;        } else {            return -1;        }    }    /**     * 一般操作顺序:     * 1. 中序 ---> 后序     * 2. 后序求值     * 现将两步合并为一步     * 使用两个栈,分别为最终结果栈 result 与操作符栈 operator,operator 预置优先级最低的 '#'     * 循环遍历中序序列,遇操作数入 result;     * 遇操作符:     * 1. '(': 直接入 operator     * 2. ')': operator 不断退栈并利用该元素计算     * 3. '+、-、*、/': 与 operator 栈顶元素比较,     * 若当前优先级<=栈顶运算符的优先级,则不断退栈并利用该元素计算;     * 否则入 operator     */    private static void solve(String infix) {        char[] array = infix.toCharArray();        for (int i = 0; i < array.length; i++) {            if (Character.isDigit(array[i])) { // 操作数                result.push(array[i] - '0');            } else {                if (array[i] == '(') {                    operator.push(array[i]);                } else if (array[i] == ')') {                    char temp = operator.pop();                    for (; temp != '('; temp = operator.pop()) {                        calculate(temp);                    }                } else if (getPriority(array[i]) <= getPriority(operator.peek())) {                    char temp = operator.peek();                    while (getPriority(array[i]) <= getPriority(temp)) {                        calculate(temp);                        operator.pop();                        temp = operator.peek();                    }                } else {                    operator.push(array[i]);                }            }        }        if (operator.peek() != '#') {            calculate(operator.pop());        }        System.out.println(result.pop());    }    public static void main(String[] args) {        operator.push('#');        solve("(2+3)*(8-2)");    }}

3. 前序(波兰)

import java.util.Stack;/** * 前序表达式求值 */public class PrefixSolution {    private Stack<Integer> result = new Stack<>();    /**     * 由于逆向扫描表达式,所以先退栈的是第一个操作数     */    private void calculate(char operator) {        int left = result.pop();        int right = result.pop();        switch (operator) {            case '+':                result.push(left + right);                break;            case '-':                result.push(left - right);                break;            case '*':                result.push(left * right);                break;            case '/':                result.push(left / right);                break;            default:                System.exit(1);                break;        }    }    /**     * 扫描从右往左进行     * 遇操作数,入 result     * 遇操作符,从 result 弹出两个操作数进行计算     * 扫描结束后,result 栈顶就是表达式结果     */    private int solve(String prefix) {        char[] array = prefix.toCharArray();        for (int i = array.length - 1; i >= 0; i--) {            if (Character.isDigit(array[i])) {                result.push(array[i] - '0');            } else {                calculate(array[i]);            }        }        return result.pop();    }    public static void main(String[] args) {        System.out.println(new PrefixSolution().solve("-32"));    }}
0 0
原创粉丝点击