数据结构 之 表达式求值

本文根据《数据结构》严蔚敏版中栈应用章节内容, 实现Java版表达式求值
其中为了简化起见,规定表达式合法, 且操作数为正整数, 操作符为+,-,*,/,(,), 辅助操作符#

import java.util.*;

/**
 * 表达式计算, 简单起见, 规定表达式合法, 且操作数为正整数, 操作符为+,-,*,/,(,), 辅助操作符#
 */
public class Demo {
    private static char[][] OPP = new char[127][127]; //Operator Priority
    static {
        // (op1, '+') = (op1,'-)
        OPP['+']['+'] = OPP['+']['-'] = '>';
        OPP['-']['+'] = OPP['-']['-'] = '>';
        OPP['*']['+'] = OPP['*']['-'] = '>';
        OPP['/']['+'] = OPP['/']['-'] = '>';
        OPP['(']['+'] = OPP['(']['-'] = '<';
        OPP[')']['+'] = OPP[')']['-'] = '>';
        OPP['#']['+'] = OPP['#']['-'] = '<';
        //(op1, '*) = (op1, '/);
        OPP['+']['*'] = OPP['+']['/'] = '<';
        OPP['-']['*'] = OPP['-']['/'] = '<';
        OPP['*']['*'] = OPP['*']['/'] = '>';
        OPP['/']['*'] = OPP['/']['/'] = '>';
        OPP['(']['*'] = OPP['(']['/'] = '<';
        OPP[')']['*'] = OPP[')']['/'] = '>';
        OPP['#']['*'] = OPP['#']['/'] = '<';

        //(op1, '(')
        OPP['+']['('] = '<';
        OPP['-']['('] = '<';
        OPP['*']['('] = '<';
        OPP['/']['('] = '<';
        OPP['(']['('] = '<';
            //OPP[')']['*']
        OPP['#']['('] = '<';

        //(op1, ')')
        OPP['+'][')'] = '>';
        OPP['-'][')'] = '>';
        OPP['*'][')'] = '>';
        OPP['/'][')'] = '>';
        OPP['('][')'] = '=';
        OPP[')'][')'] = '>';
            //OPP['#']['('] = '<';

        //(op1, '#')
        OPP['+']['#'] = '>';
        OPP['-']['#'] = '>';
        OPP['*']['#'] = '>';
        OPP['/']['#'] = '>';
            //OPP['(']['#'] = '=';
        OPP[')']['#'] = '>';
        OPP['#']['#'] = '<';
    }

    public static char precede(char op1, char op2) {
        return OPP[op1][op2];
    }

    public static int operate(int a, char op, int b) {
        switch (op) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                return a / b;
        }
        return 0;
    }

    public static int EvaluateExpression(String expssion) {
        if (expssion == null || expssion.length() == 0) return 0;

        String expsWithEnd = expssion + "#";
        char[] exps = expsWithEnd.toCharArray();

        Stack<Character> OPTR = new Stack<>();
        OPTR.push('#');
        Stack<Integer> OPND = new Stack<>();

        int k = 0;
        char ch = exps[k++];
        while(ch != '#' || OPTR.peek() != '#') {
            if (Character.isDigit(ch)) {
                int num = ch - '0';
                while(k < exps.length && Character.isDigit(ch = exps[k])) {
                    num = num * 10 + (ch - '0');
                    k++;
                }
                OPND.push(num);
                ch = exps[k++];
            } else {
                switch (precede(OPTR.peek(), ch)) {
                    case '<':
                        OPTR.push(ch);
                        ch = exps[k++];
                        break;
                    case '=':
                        //脱括号,接收下一个字符
                        OPTR.pop();
                        ch = exps[k++];
                        break;
                    case '>':
                        char op = OPTR.pop();
                        int b = OPND.pop();
                        int a = OPND.pop();
                        OPND.push(operate(a, op, b));
                        break;
                }
            }
        }//while
        return OPND.peek();
    }

    public static void main(String[] args) {
        //String exp = "3*(7-2)";
        String exp;
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
            exp = in.nextLine();
            System.out.println(EvaluateExpression(exp));
        }
    }
}
/*
3*(7-2)
15
10*(12-2)
100
 */
posted @ 2017-10-15 18:19  一弓一土两亩田  阅读(534)  评论(0编辑  收藏  举报