您的位置:首页 > 其它

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

2016-06-05 01:28 239 查看
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();

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: