1. 程式人生 > >棧---1、中綴表示式到字尾表示式的轉化 2、求解字尾表示式的值

棧---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.