利用栈的特性对一个表达式求值

来源:互联网 发布:mac暗影格斗2修改 编辑:程序博客网 时间:2024/06/04 19:18
package cn.my.stack;

import java.util.Stack;

/**
 * 利用栈的特性进行表达式求值
 *
 * @author zhu
 *
 */
public class ExpressionValue {

    // 定义一个操作数栈
    private static Stack<Integer> numberStack = new Stack<Integer>();
    // 定义一个操作符栈
    private static Stack<Character> operatorStack = new Stack<Character>();

    public static void main(String[] args) throws Exception {
        System.out.println(expGetValue());
    }

    /**
     * @param operator
     *            操作符
     * @return 操作符的优先级
     */
    public static int getPriority(char operator) {
        switch (operator) {
        case '*':
            return 2;
        case '/':
            return 2;
        case '+':
            return 1;
        case '-':
            return 1;
        case '#':
            return 0;
        }
        return 0;
    }

    /**
     * @param x
     * @param operator
     * @param y
     * @return 按指定操作符计算两个操作数的到的结果
     */
    public static int operate(Integer x, char operator, Integer y) {
        switch (operator) {
        case '*':
            return x * y;
        case '/':
            return x / y;
        case '+':
            return x + y;
        case '-':
            return x - y;
        }
        return 0;
    }

    /**
     * @return 表达是的值
     * @throws Exception
     */
    public static int expGetValue() throws Exception {
        // 定义要存储字符和操作符的变量
        char ch;
        char operator;
        // 存储操作数和结果的变量
        Integer x, y, result;
        // 初始化运算符集合
        String operators = "+ - * / #";
        // 栈初始化,在栈底压入表达式左边虚设的字符"#",用于以后判断计算是否结束
        operatorStack.push('#');
        // 读入一个字符
        ch = (char) System.in.read();
        // 如果字符不是"#"或者操作符栈的站顶元素不是"#"则继续
        while (ch != '#' || operatorStack.peek() != '#') {
            // 如果输入的字符不在操作符集合中
            if (!operators.contains(String.valueOf(ch))) {
                // 注意System.in.read()读入时,键盘上的任何一个键都会被当做时输入值,包括Enter,当我们按下Enter时,实际上发送了
                // 两个值一个回车\t,一个换行\n,所以在判断字符时要把这两个值滤去
                if (ch != '\n' && ch != '\r') {
                    // 把字符所代表的数值压入操作数栈
                    numberStack.push(Character.getNumericValue(ch));
                }
                // 再读入一个字符
                ch = (char) System.in.read();

            } else if (getPriority(ch) > getPriority(operatorStack.peek())) { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级高
                if (ch != '\n' && ch != '\r') {
                    // 则把操作符压入操作符栈
                    operatorStack.push(ch);
                }
                // 在读入一个字符
                ch = (char) System.in.read();

            } else { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级低
                // 弹出位于操作符栈顶端的操作符
                operator = operatorStack.pop();
                // 弹出两个操作数
                x = numberStack.pop();
                y = numberStack.pop();
                // 计算结果
                result = operate(y, operator, x);
                // 把中间结果压入操作数栈
                numberStack.push(result);
            }
        }
        // 最终操作数栈顶的元素就是表达式的值
        return numberStack.pop();
    }
}
1 0
原创粉丝点击