表达式求值

[参考文献:严蔚敏.数据结构(C语言版)]

表达式求值是程序设计语言编译中的一个最基本问题,它的实现是栈应用的一个典型例子.

搞了一天,有相关的好的算法请大家传上来,一起分享.

表3.1: 定义了算符之间的优先关系:

代码
  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Text;
  6 using System.Text.RegularExpressions;
  7 namespace EvaluateExpression
  8 {
  9     class EvaluateExpression
 10     {
 11         private static string  Precede(string  t1, string  t2)    //根据表3.1,判断两符号的优先关系 
 12         {
 13             string f = string.Empty;
 14             switch (t2)
 15             {
 16                 case "+":
 17                 case "-":
 18                     if (t1 == "(" || t1 == "#")
 19                         f = "<";
 20                     else
 21                         f = ">";
 22                     break;
 23                 case "*":
 24                 case "/":
 25                     if (t1 == "*" || t1 == "/" || t1 == ")")
 26                         f = ">";
 27                     else
 28                         f = "<";
 29                     break;
 30                 case "(":
 31                     if (t1 == ")")
 32                         throw new ArgumentOutOfRangeException("表达式错误");
 33                     else
 34                         f = "<";
 35                     break;
 36                 case ")":
 37                     switch (t1)
 38                     {
 39                         case "(": f = "="break;
 40                         case "#"throw new ArgumentOutOfRangeException("表达式错误"); 
 41                         default: f = ">"break;
 42                     }
 43                     break;
 44                 case "#":
 45                     switch (t1)
 46                     {
 47                         case "#": f = "="break;
 48                         case "("throw new ArgumentOutOfRangeException("表达式错误"); 
 49                         default: f = ">"break;
 50                     }
 51                     break;
 52             }
 53             return f;
 54         }
 55         private static bool In(string  c)    //判断c是否为运算符 
 56         {
 57            switch(c)
 58            {
 59               case"+":
 60               case"-":
 61               case"*":
 62               case"/":
 63               case"(":
 64               case")":
 65               case"#":  return true ;  
 66               default:  return false ;
 67            }
 68         }
 69         private static int Operate(int a, string oper, int b)
 70         {
 71             int c=0;
 72             switch (oper)
 73             {
 74                 case "+": c = a + b; break;
 75                 case "-": c = a - b; break;
 76                 case "*": c = a * b; break;
 77                 case "/": c = a / b; break;
 78             }
 79             return c;
 80           
 81         }
 82         public static int Calculate(string exp)   //算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈 
 83         {
 84     
 85             expr S = new expr(exp);      //将传过来的表达式打包成一个类对象,便于计算
 86             string C =string.Empty ;
 87             int oper1, oper2;
 88             string theta = string.Empty;
 89             Stack OPTR = new Stack();
 90             OPTR.Push("#");
 91             Stack OPND = new Stack();
 92             C = S.GetS ();                 //取表达式里的分量    
 93             while (C != "#" || OPTR.Peek().ToString() != "#")  
 94             {
 95                 if (!In(C))       //不是运算符则进栈
 96                 {
 97                     OPND.Push(C);
 98                     C = S.GetS();
 99                 }
100                 else
101                     switch (Precede(OPTR.Peek().ToString(), C))
102                     {
103                         case "<":         //栈顶元素优先权低
104                             OPTR.Push(C);
105                             C = S.GetS();
106                             break;
107                         case "=":       //脱括号并接收下一个字符
108                             OPTR.Pop();
109                             C = S.GetS();
110                             break;
111                         case ">":    //退栈并将运算结果入栈
112                             theta = OPTR.Pop().ToString();
113                             oper2 = Convert.ToInt32(OPND.Pop());
114                             oper1 = Convert.ToInt32(OPND.Pop());
115                             OPND.Push(Operate(oper1, theta, oper2).ToString());
116                             break;
117                     }//switch
118             }//while
119             return Convert.ToInt32(OPND.Peek());
120         }
121         private class expr       //表达式类, 用于取表达式里的各个分量
122         {
123             //成员
124             private string exp;
125             private int length;  //为GetS()方法服务
126            //构造器
127             public expr(string exp)
128             {
129                 this.exp = exp;
130                 length = exp.Length;
131                 if (!IsRight()) { Console.WriteLine("表达式有错"); return; }
132             }
133            //方法
134             public string GetS()          //取表达式里的字符串
135             {
136                 string ch, token, f;
137                 ch = token = f = string.Empty;
138                 if (length == 0)
139                     throw new ArgumentOutOfRangeException("表达式取完");
140                 while (length != 0)
141                 {
142                     ch = exp.Substring(exp.Length - length, 1);
143 
144                     if (IsNumeric(ch))   //是数字   : 说明第一次取的就是数字
145                     {
146                         token += ch;
147                         length--;
148                     }
149                     else                //不是数字
150                     {
151                         if (IsNumeric(token))
152                         {
153                             f = token;
154                             break;
155                         }
156                         else                       //说明第一次取的就不是数字
157                         {
158                             if (ch == " ")
159                             {
160                                 length--;
161                                 continue;
162                             }
163                             length--;             //如取的是非数字
164                             f = ch;
165                             break;
166                         }
167                     }
168                 }
169                 return f;
170             }//GetS
171             private bool IsRight()  //判断表达式是否合法: (1)两数字中间是否有空格
172             {
173                 bool f = true;
174                 string ch = string.Empty;
175                 int i = 0;
176                 int j = 0;
177                 for (int p = 0; p < exp.Length; p++)
178                 {
179                     ch = exp.Substring(p, 1);
180                     if (IsNumeric(ch))
181                     {
182                         if (j == 1return false;
183                         i = 1;
184                         continue;
185                     }
186                     if (ch == " ")
187                     {
188                         if (i == 1) j = 1continue;
189                     }
190                     i = j = 0;
191 
192                 }
193                 return f;
194 
195             }
196             private bool IsNumeric(string input)         //判断字符串是否为数
197             {
198                 bool flag = true;
199                 string pattern = (@"^\d+$");
200                 Regex validate = new Regex(pattern);
201                 if (!validate.IsMatch(input))
202                 {
203                     flag = false;
204                 }
205                 return flag;
206             }
207         }//class:expr
208     }
209 }
210 附一个测试代码:
211 using System;
212 using System.Collections.Generic;
213 using System.Linq;
214 using System.Text;
215 namespace EvaluateExpression
216 {
217     class Program
218     {
219         static void Main(string[] args)
220         {
221             Console.WriteLine ("算术表达式, 以#结束!");
222             string expression = " 3022 * ( 17 - 12) /2 #";
223             Console .WriteLine ( Convert .ToString ( EvaluateExpression.Calculate(expression)));
224             Console.ReadLine();
225         }
226     }
227 }

 

本文转自:http://www.cnblogs.com/wwewbw/archive/2010/02/11/1667538.html

posted @ 2010-07-23 15:21  tungli  阅读(335)  评论(0编辑  收藏  举报