中缀转后缀表达式

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Diagnostics;
  5 using System.Linq;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 
  9 namespace CSTEST
 10 {
 11 
 12     class Test
 13     {
 14         enum ProrLevel
 15         {
 16             None = -1,
 17             AddOrSub = 1,//+ -
 18             Mul = 2,//*/
 19             FirstParent = 100,//(
 20             SecondParent = 4,//)
 21         }
 22         private char[] operateStr = { '+', '-', '*', '/', '(', ')', };
 23         private int[] dataArr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 24 
 25         static void Main(string[] args)
 26         {
 27             Test myTest = new Test();
 28             int operateLength = myTest.operateStr.Length;
 29 
 30             string addString = "9+*2/1";
 31 
 32             List<string> midList = new List<string>();
 33             List<string> behindList = new List<string>();
 34             Stack<string> operStack = new Stack<string>();
 35 
 36             myTest.Spilt_operate_array(addString, ref midList);
 37 
 38             for (int i = 0; i < midList.Count; ++i)
 39             {
 40                 Console.Write(midList[i] + " ");
 41             }
 42             myTest.PushListToStack(ref midList, ref behindList, ref operStack);
 43 
 44             Console.WriteLine();
 45             for (int i = 0; i < behindList.Count; ++i)
 46             {
 47                 Console.Write(behindList[i] + " ");
 48             }
 49         }
 50 
 51         //对()括号的处理
 52         private void SetParent(ref Stack<string> stack, ref List<string> behidList)
 53         {
 54             string popStr = stack.Peek();
 55             while (!string.Equals(popStr, "("))
 56             {
 57                 behidList.Add(popStr);
 58                 stack.Pop();
 59                 popStr = stack.Peek();
 60             }
 61             stack.Pop();
 62         }
 63 
 64         //对整个list栈操作
 65         private void PushListToStack(ref List<string> midList, ref List<string> behindList, ref Stack<string> operFunStack)
 66         {
 67             for (int i = 0; i < midList.Count; ++i)
 68             {
 69                 char tempMid = midList[i][0];
 70                 if (Is_spilt_flag(tempMid, operateStr))
 71                 {
 72                     PushOperToStack(midList[i], ref operFunStack, ref behindList);
 73                 }
 74                 else
 75                 {
 76                     behindList.Add(midList[i]);
 77                 }
 78             }
 79             ClearOperStack(ref operFunStack,ref behindList);
 80         }
 81         //如果最后stack内还有数据,则直接压入list
 82         private void ClearOperStack(ref Stack<string> stack, ref List<string> behindList)
 83         {
 84             if (stack == null || stack.Count == 0) return;
 85             while (stack.Count != 0)
 86             {
 87                 behindList.Add(stack.Peek());
 88                 stack.Pop();
 89             }
 90         }
 91         //如果优先级比较大
 92         private void HighPrior(string pushStr, string peekStr, ref Stack<string> stack, ref  List<string> behidList)
 93         {
 94             do
 95             {
 96                 if (string.Equals(pushStr, ")"))
 97                 {
 98                     SetParent(ref stack, ref behidList);
 99                     break;
100                 }
101                 else
102                 {
103                     behidList.Add(peekStr);
104                     stack.Pop();
105                     if (stack.Count > 0)
106                     {
107                         peekStr = stack.Peek();
108                     }
109                     else
110                     {
111                         break;
112                     }
113                 }
114             } while (IsPrior(pushStr, peekStr) && stack.Count > 0);
115             if (!string.Equals(pushStr, ")"))
116             {
117                 stack.Push(pushStr);
118             }
119         }
120         //如果优先级比较小
121         private void LowPrior(string pushStr, ref Stack<string> stack)
122         {
123             stack.Push(pushStr);
124         }
125         //运算符的出栈入栈
126         private void PushOperToStack(string pushStr, ref Stack<string> stack, ref  List<string> behidList)
127         {
128             if (stack.Count == 0)
129             {
130                 stack.Push(pushStr);
131             }
132             else
133             {
134                 string peekStr = stack.Peek();
135                 if (IsPrior( peekStr,pushStr))
136                 {
137                     HighPrior(pushStr, peekStr, ref stack, ref behidList);
138                 }
139                 else
140                 {
141                     LowPrior(pushStr, ref stack);
142                 }
143             }
144         }
145 
146         //赋与运算符数值
147         private void TransToInt(char elemet, out ProrLevel level)
148         {
149             switch (elemet)
150             {
151                 case '+':
152                 case '-':
153                     level = ProrLevel.AddOrSub;
154                     break;
155                 case '*':
156                 case '/':
157                     level = ProrLevel.Mul;
158                     break;
159                 case '(':
160                     level = ProrLevel.FirstParent;
161                     break;
162                 case ')':
163                     level = ProrLevel.SecondParent;
164                     break;
165                 default:
166                     level = ProrLevel.None;
167                     Console.WriteLine("error!!没有此运算符号!");
168                     break;
169             }
170         }
171         //+-*/运算符优先级的判断;优先级相同的话,也为false,弹出stack
172         //如果为(则为false
173         private bool IsPrior(string inStack, string pushToStack)
174         {
175             ProrLevel inStackLevel;
176             TransToInt(char.Parse(inStack), out inStackLevel);
177             //if (inStackLevel==ProrLevel.FirstParent)
178             //{
179             //    return false;
180             //}
181             ProrLevel pushToStackLevel;
182             TransToInt(char.Parse(pushToStack), out pushToStackLevel);
183             if ((int)pushToStackLevel >= (int)inStackLevel)
184             {
185                 return true;
186             }
187             return false;
188         }
189 
190         #region 对表达式进行拆分
191         //对表达式进行拆分
192         private void Spilt_operate_array(string opArr, ref List<string> midArrlist)
193         {
194             if (string.IsNullOrEmpty(opArr))
195             {
196                 Console.WriteLine("空,不是表达式!!");
197             }
198             char oldChar = opArr[0];
199             string tempData = oldChar.ToString();
200             string tempOper = string.Empty;
201             if (Is_spilt_flag(oldChar, operateStr))
202             {
203                 Console.WriteLine("第一个字符出错,不是表达式!!");
204             }
205             oldChar = opArr[opArr.Length - 1];
206             if (Is_spilt_flag(oldChar, operateStr))
207             {
208                 Console.WriteLine("最后一字符出错,不是数字!!");
209             }
210             for (int i = 1; i < opArr.Length; ++i)
211             {
212                 bool bNumber = Is_number(opArr[i], dataArr);
213 
214                 if (bNumber)
215                 {
216                     tempData += opArr[i].ToString();
217                     if (i == opArr.Length - 1)
218                     {
219                         midArrlist.Add(tempData);
220                     }
221                     tempOper = string.Empty;
222                 }
223                 else
224                 {
225                     if (!string.IsNullOrEmpty(tempData))
226                     {
227                         midArrlist.Add(tempData);
228                         tempData = string.Empty;
229                     }
230                     IsTwoOper(tempOper,opArr[i].ToString());
231                     tempOper = opArr[i].ToString();
232                     bool bOper = Is_spilt_flag(opArr[i], operateStr);
233                     if (bOper)//运算符,进行拆分
234                     {
235                         midArrlist.Add(opArr[i].ToString());
236                     }
237                     else
238                     {
239                         Console.WriteLine("不是数字 不是运算符号 不是表达式!!");
240                         break;
241                     }
242                 }
243             }
244             
245         }
246         //两个非括号的运算符在一起,则不是表达式
247         private void IsTwoOper(string tempStr,string operString)
248         {
249             if (!string.IsNullOrEmpty(tempStr))
250             {
251                 if (!IsKuoHao(tempStr) && !IsKuoHao(operString))
252                 {
253                     Console.WriteLine("两个运算符在一起了!!");
254                     return;
255                 }
256             }
257         }
258         private bool IsKuoHao(string testStr)
259         {
260             if (string.Equals(testStr,"(")||string.Equals(testStr,")"))
261             {
262                 return true;
263             }
264             return false;
265         }
266         #endregion
267 
268         #region 判断是数字还是运算符
269         //检测一个字符是否是+-*、(),是的话进行拆分到list里
270         private bool Is_spilt_flag(char spiltChar, char[] opArr)
271         {
272             for (int i = 0; i < opArr.Length; ++i)
273             {
274                 if (Char.Equals(spiltChar, opArr[i]))
275                 {
276                     return true;
277                 }
278             }
279             return false;
280         }
281         //是否是数字0-9
282         private bool Is_number(char element, int[] elemArray)
283         {
284             int data = element - 48;
285 
286             for (int i = 0; i < elemArray.Length; ++i)
287             {
288                 if (data == elemArray[i])
289                 {
290                     return true;
291                 }
292             }
293             return false;
294         }
295         #endregion
296     }
297 
298 }