1. 程式人生 > >用棧計算數學表達式的值

用棧計算數學表達式的值

append 插入元素 插入 構造 ++ app equals his trac

用棧計算數學表達式的值

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

兩個概念:

中綴表達式(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 }

用棧計算數學表達式的值