1. 程式人生 > >棧應用1:算術表示式求值

棧應用1:算術表示式求值

主要要理解字尾表示式是怎麼由中綴表示式得來的
多寫寫算術表示式實際是怎麼運算的(順序)
字尾表示式是怎麼運算的
使用(來提升運算子的優先順序
運算子總是跟在第二個操作元的後面

package Evaluation;

import java.util.Scanner;

class Stack
{
    final int MaxSize = 10;
    char[] data = new char[MaxSize];
    int top;

    public Stack()
    {
        top = -1;
    }
}

// 運算子優先順序
class Priority
{
    final
int MaxOp = 7; final char[] ch = { '=', '(', '+', '-', '*', '/', ')' }; // 運算子 final int[] lpri = { 0, 1, 3, 3, 5, 5, 6 }; // 左運算子優先順序 final int[] rpri = { 0, 6, 2, 2, 4, 4, 1 }; // 右運算子優先順序 } public class Main { public static void main(String args[]) { Scanner cin = new Scanner(System.in); String exp = cin.nextLine(); exp = exp + "\0"
; char postexp[] = new char[30]; trans(exp, postexp); System.out.println("中綴表示式:" + exp); int i = 0; char ch = postexp[i]; while (ch != '\0') { System.out.print(ch); ch = postexp[++i]; } System.out.println(); System.out.println("表示式的值:"
+ compvalue(postexp)); } // 判斷是否為運算子 public static boolean IsOp(char ch) { Priority pri = new Priority(); for (int i = 0; i < pri.MaxOp; i++) if (ch == pri.ch[i]) return true; return false; } // 求左運算子op的優先順序 public static int leftpri(char op) { Priority pri = new Priority(); for (int i = 0; i < pri.MaxOp; i++) if (op == pri.ch[i]) return pri.lpri[i]; return 0; } // 求右運算子op的優先順序 public static int rightpri(char op) { Priority pri = new Priority(); for (int i = 0; i < pri.MaxOp; i++) if (op == pri.ch[i]) return pri.rpri[i]; return 0; } // 返回op1與op2運算子優先順序的比較結果 public static int Precede(char op1, char op2) { if (leftpri(op1) == rightpri(op2)) return 0; else if (leftpri(op1) < rightpri(op2)) return -1; else return 1; } // 將算術表示式exp轉換成字尾表示式postexp public static void trans(String exp, char[] postexp) { int i = 0; Stack Sop = new Stack(); Sop.top++; Sop.data[Sop.top] = '='; // 將'='入棧 int n = 0; char ch = exp.charAt(n); while (ch != '\0') { if (!IsOp(ch)) { while (ch >= '0' && ch <= '9') { postexp[i++] = ch; ch = exp.charAt(++n); } postexp[i++] = '#'; } else { switch (Precede(Sop.data[Sop.top], ch)) { case -1: // 棧頂運算子優先順序低 Sop.data[++Sop.top] = ch; ch = exp.charAt(++n); // 繼續掃描其他字元 break; case 0: // 只有括號滿足這種情況 Sop.top--; // 退棧 ch = exp.charAt(++n); // 繼續掃描其他字元 break; case 1: postexp[i++] = Sop.data[Sop.top--]; // 退棧並輸出到postexp中 break; } } } while (Sop.data[Sop.top] != '=') { postexp[i++] = Sop.data[Sop.top--]; } postexp[i] = '\0'; } // 計算字尾算數表示式 public static float compvalue(char[] postexp) { Stack st = new Stack(); float d, a, b, c; int i = 0; char ch = postexp[i]; while (ch != '\0') { switch (ch) { case '+': a = st.data[st.top--]; b = st.data[st.top--]; c = b + a; st.data[++st.top] = (char) c; break; case '-': a = st.data[st.top--]; b = st.data[st.top--]; c = b - a; st.data[++st.top] = (char) c; break; case '*': a = st.data[st.top--]; b = st.data[st.top--]; c = b * a; st.data[++st.top] = (char) c; break; case '/': a = st.data[st.top--]; b = st.data[st.top--]; if (a != 0) { c = b / a; st.data[++st.top] = (char) c; } else { System.out.println("除0錯誤"); } break; default: d = 0; while (ch >= '0' && ch <= '9') { d = 10 * d + (ch - '0'); ch = postexp[++i]; } st.data[++st.top] = (char) d; break; } ch = postexp[++i]; } return st.data[st.top]; } }

輸入:
1+3*2-1
輸出:
中綴表示式:1+3*2-1
1#3#2#*+1#-
表示式的值:6.0
輸入:
(56-20)/(4+2)
輸出:
中綴表示式:(56-20)/(4+2)
56#20#-4#2#+/
表示式的值:6.0