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 }