constchar ONE = '1'; constchar TWO = '2'; constchar THREE = '3'; constchar FOUR = '4'; constchar FIVE = '5'; constchar SIX = '6'; constchar SEVEN = '7'; constchar EIGHT = '8'; constchar NINE = '9'; constchar ZERO = '0';
public Stack<int> numberStack = new Stack<int>(); public Stack<char> symbolStack = new Stack<char>();
public Stack<int> firstNumberStack = new Stack<int>(); public Stack<char> firstSymbolStack = new Stack<char>();
public Stack<int> secondNumberStack = new Stack<int>(); public Stack<char> secondSymbolStack = new Stack<char>();
staticvoidMain(string[] args) { Program p = new Program(); string expression = "2 + (3 +( 3 *4 - 5 / ( 2 +3))*4 - 6) + 6"; int ret = p.Calculate(expression); Console.WriteLine(ret); }
intCalculate(string expression) { bool numberStart = false; StringBuilder numberStr = new StringBuilder(); char[] expressionCharArray = expression.ToCharArray(); for (int i = 0; i < expressionCharArray.Length; i++ ) { char c = expressionCharArray[i]; #region push the number to stack switch (ParseCharOfCharacterType(c)) { case CharacterType.NUMBER: numberStart = true; numberStr.Append(c); if (i == expressionCharArray.Length - 1)//如果是最后一个字符那么也应该计算出数字并入栈 { int num = 0; if (int.TryParse(numberStr.ToString(), out num)) { numberStack.Push(num); numberStart = false; numberStr.Clear(); } else { Console.WriteLine("非法数字!"); return0; } } break; case CharacterType.OPERATOR: case CharacterType.PORIORITYSIGN: if (numberStart) { int num = 0; if (int.TryParse(numberStr.ToString(), out num)) { numberStack.Push(num); numberStart = false; numberStr.Clear(); } else { Console.WriteLine("非法数字!"); return0; } } break; } #endregion
switch (ParseCharOfCharacterType(c)) { case CharacterType.OPERATOR: symbolStack.Push(c); break; case CharacterType.PORIORITYSIGN: switch (c) { case LEFTBRACKET: symbolStack.Push(c); break; case RIGHTBRACKET: firstNumberStack.Push(numberStack.Pop()); while (symbolStack.Peek() != LEFTBRACKET) { firstSymbolStack.Push(symbolStack.Pop()); firstNumberStack.Push(numberStack.Pop()); } symbolStack.Pop();// 移除左括号 DoP1Calculator(); DoP2Calculator(); break; } break; } }
voidDoP1Calculator() { // 这个方法只处理表达式的乘法和除法: // 以这个算式为例3 *4 - 5 / 5,最后的结果为 // 12 - 1 secondNumberStack.Push(firstNumberStack.Pop()); while (firstSymbolStack.Count > 0) { switch (firstSymbolStack.Peek()) { case ADDSYMBOL: case SUBSYMBOL: secondNumberStack.Push(firstNumberStack.Pop()); secondSymbolStack.Push(firstSymbolStack.Pop()); break; case MULSYMBOL: int leftValue = secondNumberStack.Pop(); int rightValue = firstNumberStack.Pop(); int ret = leftValue * rightValue; firstSymbolStack.Pop(); // 移除乘号 secondNumberStack.Push(ret); break; case DIVSYMBOL: int leftVal = secondNumberStack.Pop(); int rightVal = firstNumberStack.Pop(); int retVal = leftVal / rightVal; firstSymbolStack.Pop(); // 移除除号 secondNumberStack.Push(retVal); break; } } }
voidDoP2Calculator() { secondNumberStack = StackUtil<int>.ReverseStack(secondNumberStack); secondSymbolStack = StackUtil<char>.ReverseStack(secondSymbolStack); while (secondSymbolStack.Count > 0) { int leftValue = secondNumberStack.Pop(); int rightValue = secondNumberStack.Pop(); switch (secondSymbolStack.Pop()) { case ADDSYMBOL:
secondNumberStack.Push(leftValue + rightValue); break; case SUBSYMBOL: secondNumberStack.Push(leftValue - rightValue); break; } } numberStack.Push(secondNumberStack.Pop()); } CharacterType ParseCharOfCharacterType(char c) { CharacterType ret = CharacterType.UNKNOWN; switch (c) { case ADDSYMBOL: ret = CharacterType.OPERATOR; break; case SUBSYMBOL: ret = CharacterType.OPERATOR; break; case DIVSYMBOL: ret = CharacterType.OPERATOR; break; case MULSYMBOL: ret = CharacterType.OPERATOR; break; case ONE: ret = CharacterType.NUMBER; break; case TWO: ret = CharacterType.NUMBER; break; case THREE: ret = CharacterType.NUMBER; break; case FOUR: ret = CharacterType.NUMBER; break; case FIVE: ret = CharacterType.NUMBER; break; case SIX: ret = CharacterType.NUMBER; break; case SEVEN: ret = CharacterType.NUMBER; break; case EIGHT: ret = CharacterType.NUMBER; break; case NINE: ret = CharacterType.NUMBER; break; case ZERO: ret = CharacterType.NUMBER; break; case LEFTBRACKET: ret = CharacterType.PORIORITYSIGN; break; case RIGHTBRACKET: ret = CharacterType.PORIORITYSIGN; break; default: ret = CharacterType.UNKNOWN; break; }