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 }