用棧計算數學表達式的值


                                    用棧計算數學表達式的值

計算一個簡單數學表達式(+ - * / ( ))的結果,有的這些符號的計算,常常需要看優先級來決定先算哪部分,計算機就是這個原理

兩個概念:

中綴表達式(infix Expression):運算符寫在兩個操作數之間(運算符有一定的優先級,可以用圓括號改變運算順序)

前/后綴表達式(prefix/postfix Expression):運算符寫在兩個表達式之前/之后(運算符沒有優先級,沒有括號,遇到運算符對它前面的兩個操作數進行求值)

如中綴表達式“6*(8+7)/5”,換成后綴表達式為“6 8 7 + * 5 /”

編程思路:

函數toPostfix(),用運算符棧來存運算符,從中綴表達式第一個字符開始,如果是數字,直接加到postfix,如果是運算符號,判斷和棧頂的優先級,不比棧頂的符號優先級低則入棧,(注意:棧中的“(”優先級最低,),否則,要棧頂出棧,如果是左括號,直接入棧,如果是右括號,則出棧,直到棧頂為左括號為止。

函數toValue(),用操作數棧來存數字,從后綴表達式第一個字符開始,是數字,就入棧,是運算符號就用棧頂的兩個數計算結果值,結果入棧。

下面是具體代碼,可以幫助理解:

       元素存儲,我選擇用順序表(SeqList<T>)

  1 //Stack<T>接口
  2 public interface Stack<T> {
  3     public abstract boolean isEmpty();
  4 
  5     public abstract void push(T x); // 元素x入棧
  6 
  7     public abstract T peek(); // 返回棧頂元素
  8 
  9     public abstract T pop(); // 出棧,返回出棧元素
 10 
 11 }
 12 //順序棧,使用順序表存儲
 13 public class SeqStack<T> implements Stack<T> {
 14     private SeqList<T> list;
 15 
 16     public SeqStack(int length) {
 17         this.list = new SeqList<T>(length); // 構造容量為length的空棧
 18     }
 19 
 20     public SeqStack() {
 21         this(64); // 構造默認容量的空棧,調用上一個構造函數
 22     }
 23 
 24     public boolean isEmpty() {
 25         return this.list.isEmpty();
 26     }
 27 
 28     public void push(T x) { // 順序表表尾插入元素
 29         list.insert(x);
 30     }
 31 
 32     public T peek() {
 33         return this.list.get(list.size() - 1);
 34     }
 35 
 36     public T pop() {
 37         return list.remove(list.size() - 1);
 38     }
 39 }
 40 //計算數學表達式
 41 public class Calculate {
 42     // 中綴表達式轉化成后綴表達式,把運算符進入到運算符棧
 43     public static StringBuffer toPostfix(String infix) {
 44         Stack<String> st = new SeqStack<String>(infix.length());
 45         StringBuffer sb = new StringBuffer(2 * infix.length());
 46         int i = 0;
 47         while (i < infix.length()) {
 48             char ch = infix.charAt(i);
 49             switch (ch) {
 50             case '+':
 51             case '-':
 52                 while (!st.isEmpty() && !st.peek().equals("("))
 53                     // 棧頂不是“(”,那么都不比"+-"低,都要出棧
 54                     sb.append(st.pop());
 55                 st.push(ch + "");
 56                 i++;
 57                 break;
 58             case '*':
 59             case '/':
 60                 while (!st.isEmpty()
 61                         && (st.peek().equals("*") || st.peek().equals("/")))
 62                     sb.append(st.pop());
 63                 st.push(ch + "");
 64                 i++;
 65                 break;
 66             case '(':
 67                 st.push(ch + "");
 68                 i++;
 69                 break;
 70             case ')':
 71                 String out = st.pop(); // 出棧,直到為"("
 72                 while (out != null && !out.equals("(")) {
 73                     sb.append(out);
 74                     out = st.pop();
 75                 }
 76                 i++;
 77                 break;
 78 
 79             default:
 80                 while (i < infix.length() && ch >= '0' && ch <= '9') {
 81                     sb.append(ch);
 82                     i++;
 83                     if (i < infix.length()) {
 84                         ch = infix.charAt(i);
 85                     }
 86                 }
 87                 sb.append(" ");
 88                 break;
 89             }
 90 
 91         }
 92 
 93         while (!st.isEmpty())
 94             // 剩下的出棧
 95             sb.append(st.pop());
 96         return sb;
 97     }
 98 
 99     // 后綴表達式的計算結果,運算結果入棧
100     public static int toValue(StringBuffer postfix) {
101         Stack<Integer> st = new SeqStack<Integer>(postfix.length());
102         int value = 0;
103         for (int i = 0; i < postfix.length(); i++) {
104             char ch = postfix.charAt(i);
105             if (ch >= '0' && ch <= '9') {
106                 value = 0; // 一定要先讓value初始值為0
107                 while (ch != ' ') {
108                     value = value * 10 + ch - '0'; // 字符轉化為數值
109                     ch = postfix.charAt(++i); // 如果這個字符為多位數
110                 }
111                 st.push(value);
112             } else {
113                 if (ch != ' ') {
114                     int y = st.pop(), x = st.pop(); // Integer自動轉化為int類型
115 
116                     switch (ch) {
117                     case '+':
118                         value = x + y;
119                         break;
120                     case '-':
121                         value = x - y;
122                         break;
123                     case '*':
124                         value = x * y;
125                         break;
126                     case '/':
127                         value = x / y;
128                         break;
129 
130                     }
131 
132                     st.push(value);
133                 }
134             }
135 
136         }
137         return st.pop(); // 結果就在棧頂
138 
139     }
140 
141 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM