在JavaScript中實現四則運算很簡單,只需要調用eval函數就行了,但是不知道什么原因萬能的.NET卻沒有封裝這個函數~
在這里為大家封裝了一個C#版本的eval函數,具體的設計參考了《大話數據結構》
1. 中綴表達式
中綴表達式即我們平時使用的四則運算表達式,如:9+(3-1)*3+10/2,但是程序卻很難識別這樣的表達式,所以需要把它轉化成后綴表達式
2. 后綴表達式
因為所有的運算符都在數字后面,所以稱其為后綴表達式,如:9 3 1 – 3 * + 10 2 / +,那么程序如何識別后綴表達式呢,這里就用到了棧(Stack),主要分以下步驟:
1) 將字符從前往后進行入棧操作
2)如果字符為數字則直接入棧,如:上例中的9、3、1都直接入棧
3)如果為運算符則獲取棧頂的兩個數字,即執行兩次pop操作,如:在執行到上例中的“-”時,將3、1出棧,然后運行3-1
4)將上一步運算的結果入棧,即將3-1=2入棧
5) 根據以上原則,運行的順序如下:3-1=2,2*3=6,9+6=15,10/2=5,15+5=20,20就是我們想要的結果
3. 中綴表達式轉后綴表達式
這里還是得用到棧(Stack),我們還是用 9+(3-1)*3+10/2 來做例子,原則如下:
1)將字符從前往后進行入棧操作
2)當字符為數字時直接輸出,如:上例中9直接輸出
3)當字符為運算符時,如果是空棧則直接入棧,如下圖步驟1
4)如果是“(”則直接入棧,如步驟2
5) 如果是“)”則循環取出棧內元素,直到“(”出棧,再將“()”內的運算符輸出,如步驟4
6)如果是“*”或“/”則直接入棧,如步驟5
7)如果是“+”或“-”,且棧頂的運算符為“*”或“/”,則取出所有棧內元素輸出,然后將本次操作符入棧,如步驟6
8)表達式遍歷完成后,循環取出棧內元素進行輸出,我們最后得到的結果就是 9 3 1 – 3 * + 10 2 / +
4.實現源碼如下:

1 public class Calculator 2 { 3 public Calculator() 4 { 5 _OptStack = new Stack<char>(); 6 _SuffixStack = new Stack<float>(); 7 } 8 9 private Stack<char> _OptStack; 10 private Stack<float> _SuffixStack; 11 12 public float Calculate(string expression) 13 { 14 string lastNum = string.Empty; 15 for (int i = 0; i < expression.Length; i++) 16 { 17 if (char.IsNumber(expression[i]) || expression[i].Equals('.')) 18 { 19 lastNum += expression[i]; 20 } 21 else 22 { 23 if (lastNum != string.Empty) 24 { 25 Merger(float.Parse(lastNum)); 26 lastNum = string.Empty; 27 } 28 AddOpt(expression[i]); 29 } 30 } 31 if (lastNum != string.Empty) 32 { 33 Merger(float.Parse(lastNum)); 34 } 35 while (_OptStack.Count > 0) 36 { 37 Merger(_OptStack.Pop()); 38 } 39 40 return _SuffixStack.Pop(); 41 } 42 43 private void AddOpt(char opt) 44 { 45 if (_OptStack.Count == 0) 46 { 47 _OptStack.Push(opt); 48 return; 49 } 50 if (opt.Equals(')')) 51 { 52 while (!_OptStack.Peek().Equals('(')) 53 { 54 Merger(_OptStack.Pop()); 55 } 56 _OptStack.Pop(); 57 return; 58 } 59 char tempOpt = _OptStack.Peek(); 60 if ((opt.Equals('-') || opt.Equals('+')) && 61 (tempOpt.Equals('*') || tempOpt.Equals('/'))) 62 { 63 while (_OptStack.Count > 0) 64 { 65 Merger(_OptStack.Pop()); 66 } 67 } 68 69 _OptStack.Push(opt); 70 } 71 72 private void Merger(float exp) 73 { 74 _SuffixStack.Push(exp); 75 } 76 77 private void Merger(char exp) 78 { 79 float num1 = _SuffixStack.Pop(); 80 float num2 = _SuffixStack.Pop(); 81 float result = 0; 82 switch (exp) 83 { 84 case '+': 85 result = num2 + num1; 86 break; 87 case '-': 88 result = num2 - num1; 89 break; 90 case '*': 91 result = num2 * num1; 92 break; 93 case '/': 94 result = num2 / num1; 95 break; 96 } 97 _SuffixStack.Push(result); 98 } 99 }
5. 下載