栈---1、中缀表达式到后缀表达式的转化 2、求解后缀表达式的值

一、中缀表达式及后缀表达式

例:典型的计算顺序为2+2*3+5=?
上面这个表达式也被成为中缀表达式。
它可以表示为2*3的乘积存为a1,让a1与2相加得到a2,最后5和a2相加得到a3,a3即为该表达式的值。
这种计算顺序可书写成:223*+5+。这便是后缀表达式。

二、实现代码

中缀表达式到后缀表达式的转化:

public class Question {
    public static void getResult() {
        Stack<Character> stack = new Stack<>();
        String expression;
        Character token;
        int i = 0;

        Scanner scanner = new Scanner(System.in);
        expression = scanner.next();

        while ((token = expression.charAt(i++)) != '=') {
            if (token >= 'a' && token <= 'z') {
                System.out.print(token + " ");// 非操作符直接输出
            } else {
                switch (token) {
                case ')':// 1、移除栈中元素直到(,包括(
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        System.out.print(stack.pop() + " ");
                    }
                    stack.pop();// 移除(
                    break;
                case '(':// 2、(的优先级最高,直接放入
                    stack.push(token);
                    break;
                case '^':// 取幂运算符//3、除了(,其它操作符均弹出
                    while (!stack.isEmpty() && !(stack.peek() == '^') && !(stack.peek() == '(')) {
                        System.out.print(stack.pop() + " ");
                    }
                    break;
                case '*':
                case '/':
                    // 弹出栈元素,碰见比*,/优先级低的为止
                    while (!stack.isEmpty() && stack.peek() != '+' && stack.peek() != '-' && stack.peek() != '(') {
                        System.out.print(stack.pop() + " ");
                    }
                    stack.push(token);
                    break;
                case '+':
                case '-':
                    // 除了(外,从栈中弹出元素,直至遇见一个优先级更低的元素
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        System.out.print(stack.pop() + " ");
                    }
                    stack.push(token);
                    break;
                }
            }
        }
        while (!stack.isEmpty()) {
            System.out.print(stack.pop());
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 中缀:a+b*c+(d*e+f)*g=
        // 后缀:a b c * + d e * f + g *+
        getResult();
    }

}

后缀表达式的计算:

public class Question {
    public static  double getResult(){
        Stack<Double> stack=new Stack<>();
        String token;
        Double a,b,result=0.0;
        boolean isNumber;

        Scanner scanner=new Scanner(System.in);
        token=scanner.next();
        //等于号作为结束符号
        while(token.charAt(0)!='='){
            try {
                isNumber=true;
                result=Double.parseDouble(token);
            } catch (Exception e) {
                isNumber=false;//发生异常说明输入的为字母,否则为数字
            }
            if(isNumber){
                stack.push(result);//数字放入栈中
            }else{
                //如果是运算符,则从栈中取出两个数完成对象的操作再放入栈中
                switch (token.charAt(0)) {
                case '+':
                    a=stack.pop();
                    b=stack.pop();
                    stack.push(a+b);
                    break;
                case '-':
                    a=stack.pop();
                    b=stack.pop();
                    stack.push(a-b);
                    break;
                case '*':
                    a=stack.pop();
                    b=stack.pop();
                    stack.push(a*b);
                    break;
                case '/':
                    a=stack.pop();
                    b=stack.pop();
                    stack.push(a/b);
                    break;
                case '^'://取幂运算
                    a=stack.pop();
                    b=stack.pop();
                    stack.push(Math.pow(b, a));
                    break;
                default:
                    break;
                }
            }
            token=scanner.next();
        }
        return stack.peek();//返回栈顶元素
    }

    public static void main(String[] args) {
        System.out.println(getResult());
        /*
         * 1
         * 2
         * 1
         * +
         * =
         * 3.0
         */
    }

}

三、总结

1、中缀到后缀的转化主要就是:(特别情况)除非处理一个)时,否则绝对不会弹出(;(普通)弹出优先级大于等于要处理的元素,直到遇见优先级更低的为止。
2、通过栈的后进先出特性可以很好地计算后缀表达式的值。遇见一个数时就把它放入栈中,遇见一个运算符时,则该运算符就作用于该栈弹出的两各数上,并把得到的结果放入栈中。

Life is a journey. What we should care about is not where it’s headed but what we see and how we feel.

posted @ 2018-01-10 20:47  晓风残月龙  阅读(101)  评论(0编辑  收藏  举报