C#實現eval 進行四則運算(有碼)


在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     }
View Code

 

5. 下載

 Demo.rar

 

 


免責聲明!

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



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