Use Stack to perform operations on the integer value's arithmetic expression string C #,
Here, if you perform an operation on the expression "(6 + (7 + 8)-9) * 9 + 8/2)-3)/2. Those who have been familiar with this class know that this expression has an operator priority and cannot perform operations from left to right. We use the OperandStack and OperatorStack operators stack to compare operators, after determining the priority, extract the operands for calculation.
The algorithm IDEA is as follows:
1. first, determine the priority of the operator. *,/is greater than +,-, (when the operator is greater than *,/, *,/, or +, or-, the operator is the first ,) the minimum priority and offset from (when an encounter occurs)
2. traverse the string from left to right, traverse one character at a time, and set the temporary numeric storage variable OperandTemp
① When an operator is encountered, if OperandTemp has a value, press the number into OperandStack.
② Loop OperatorStack until OperatorStack has no value, and then compare the operator with the operator at the top of OperatorStack. If the operator has a high priority, press the operator into the stack and exit the loop; if the operation priority of this operator is low, the operator at the top of the OperatorStack stack is taken out of ope1, and the two numbers a1 (first-out stack) and a2 at the top are taken out from the OperandStack, note that the second operand is performed for the first output stack.
A2 ope1 a1; obtain the result in OperandStack; if this operator is ),
③ When the loop ends, there will be two remaining conditions, that is, there is one operator left in OperatorStack, there are two remaining operators, and the last operator has a high priority, then, read the last number and the number at the top of the OperandStack to perform an operation, obtain the result, and then perform the operation.
Take the string "(6 + (7 + 8)-9) * 9 + 8/2)-3)/2" as an example. The algorithm's operation process is, first (Press OperatorStack to [(], press 6 into OperandStack [6], to +, because (not involved in the operation, then press +
OperatorStack [(+), the next character (with a higher priority than the + at the top of OperatorStack) will be (pushed to OperatorStack [(+ (], next (Press OperatorStack [(+ (), 7 Press OperandStack [6, 7], and the next plus Press
OperatorStack [(+), 8 press into OperandStack [6, 7, 8], next) with a priority less than + at the top of OperatorStack, then, the plus (+) at the top of the OperandStack 8 and 7 and OperatorStack are taken out, and the operation result is 15 pushed to the OperandStack to continue the comparison.) The Plus (, with the same priority and eliminated at the same time (, at this time, OperatorStack is [(+ (], OperandStack bits [6, 15], the next character-less than (, into the stack [(+ (-), 9 into the stack OperandStack is [6, 15, 9]; next), take out-and 15, 9 for 6 operations, into the stack OperandStack [6, 6];) Eliminate the stack top (OperatorStack is [(+]; next * Similarly, operandStack [6, 6], OperatorStack is [(+ *]; next 9 into Stack OperandStack [6, 6, 9]; next +, priority less *, 6*9 = 54 into the stack, OperandStack [6, 54], OperatorStack is [(+]; next +, with a low priority, then, the top of the stack + 6 + 54 = 60 into the stack OperandStack [60], press this operator + OperatorStack to [(+]; the next 8 into the stack OperandStack [60, 8 ]; next/, with a higher priority, and 2 in the stack, OperatorStack is set to [(+/], OperandStack is set to [, 2]; next) with a lower priority
OperatorStack is [(+], OperandStack [60, 4] =, OperatorStack is [(], OperandStack [64]; next-in stack, 3 in stack OperatorStack is 【(-], operandStack [64, 3]; next), then 64-3 = 61 into the stack, OperatorStack is [null], OperandStack [61]; next/into the stack, 2 into the stack, operatorStack: [/], OperandStack: [61/2]; this is the case of the remaining operator. The final calculation result is: 30.5 =.
The implementation code is as follows:
1 static char [] Operators = new char [] {'+ ','-','*','/','(',')'}; 2 static void Main (string [] args) 3 {4 float a = EvaluateExpression ("10 + (80*3 + (6 + 7) * 2"); 5 Console. writeLine (a); 6 Console. readKey (); 7 8} 9 // <summary> 10 // initialize operator Priority 11 /// </summary> 12 // <param name = "a"> </param> 13 // <param name = "B"> </param> 14 // <returns> </returns> 15 static char InitPriorities (char, char B) 16 {17 int aIndex =-1; 18 int bIndex =-1; 19 for (int I = 0; I <Operators. length; I ++) 20 {21 if (Operators [I] = a) 22 aIndex = I; 23 if (Operators [I] = B) 24 bIndex = I; 25 26} 27 char [,] Priorities = new char [6, 6] {'>', '>', '<', '>'}, 28 {'>', '>', '<', '>'}, 29 {'> ', '>', '<', '>'}, 30 {'>', '> ', '<', '>'}, 31 {'<', '='}, 32 {'? ','? ','? ','? ','? ','? '}}; 33 return Priorities [aIndex, bIndex]; 34} 35 static float Calculate (float Operand1, float Operand2, char Operator) 36 {37 float Ret = 0; 38 if (Operator = '+') 39 {40 Ret = Operand1 + Operand2; 41} 42 else if (Operator = '-') 43 {44 Ret = Operand1-Operand2; 45} 46 else if (Operator = '*') 47 {48 Ret = Operand1 * Operand2; 49} 50 else if (Operator = '/') 51 {52 Ret = Operand1/O Perand2; 53} 54 55 return Ret; 56} 57 static float EvaluateExpression (string str) 58 {59 Stack <float> OperandStack = new Stack <float> (); // operand Stack, 60 Stack <char> OperatorStack = new Stack <char> (); // operator Stack 61 float OperandTemp = 0; 62 63 char LastOperator = '0 '; // record the last encountered operator 64 65 for (int I = 0, size = str. length; I <size; ++ I) 66 {67 char ch = str [I]; 68 69 if ('0' <= ch & ch <= '9 ') 70 {/ /Read an operand 71 OperandTemp = OperandTemp * 10 + ch-'0 '; 72} 73 else if (ch = '+' | ch = '-' | ch = '*' | ch = '/' | 74 ch = '(' | ch = ') ') 75 {76 // There are two cases where no operands need to be stored in the stack. 77 // 1 the current operator is "(". (The operator on the left is already responsible for the operations into the stack. 78 // 2 the last encountered operator is ")".) Will be responsible for the operations into the stack.) The operators followed by the operations do not need to be responsible for the operations into the stack. 79 if (ch! = '(' & LastOperator! = ') 80 {81 // when an operator is encountered, it means that the previously read operand has ended. Save operations. 82 OperandStack. Push (OperandTemp); 83 // clear to prepare for reading the next operator. 84 OperandTemp = 0; 85} 86 87 // The currently encountered operator is used as operator 2, and the previously encountered operator (as operator 1) is given a priority comparison with 88 char Opt2 = ch; 89 90 for (; OperatorStack. count> 0;) 91 {92 // compare the current operator with the priority of the previous operator (the top operator) 93 char Opt1 = OperatorStack. peek (); 94 char CompareRet = InitPriorities (Opt1, Opt2); 95 if (CompareRet = '>') 96 {// if operator 1 is greater than operator 2, operator 1 should calculate 97 98 // retrieve the previously saved operand 2 99 float Operand2 = OperandStack. pop (); 100 101 // retrieved Operand 1 102 float Operand1 = OperandStack. Pop (); 103 104 // retrieve the previously saved operator. This operator is currently computed. After the computation is complete, it is unnecessary to save it if it is eliminated. 105 OperatorStack. Pop (); 106 107 // binary operator calculation. Save the calculation result. 108 float Ret = Calculate (Operand1, Operand2, Opt1); 109 OperandStack. push (Ret); 110} 111 else if (CompareRet = '<') 112 {// if operator 1 is less than operator 2, note: operators 1 and 2 cannot be calculated at present, 113 // exit the loop, and record operators. 114 break; 115} 116 else if (CompareRet = ') 117 {118 // when the operator is equal, only operator 2 is ")", when operand 1 is "(", 119 // The previously saved operator "(" indicates that "(", ")" has been removed from each other, the brackets have been calculated 120 OperatorStack. pop (); 121 break; 122} 123 124} // end for 125 126 // Save the currently encountered operator. The current operator still lacks the right operand, which can be computed only after the right operand is read. 127 if (Opt2! = ') 128 {129 OperatorStack. push (Opt2); 130} 131 132 LastOperator = Opt2; 133} 134 135} // end for 136 137 138/* 139 The for above will traverse the expression while calculating, if it can be calculated. 140 when the traversal is complete, the entire expression is not computed. There are two cases: 141 1. The remaining one operator. 142 2. The remaining two operators, and operator 1 is smaller than operator 2. In this case, the above traversal process cannot be computed, so it will be left behind. From 143 to here, priority comparison is no longer required. Case 1 and Case 2 are the operators that are retrieved cyclically for calculation. 144 */145 if (LastOperator! = ') 146 {147 OperandStack. push (OperandTemp); 148} 149 for (; OperatorStack. count> 0;) 150 {151 // retrieve the previously saved operand 2 152 float Operand2 = OperandStack. pop (); 153 154 // retrieve the previously stored operand 1 155 float Operand1 = OperandStack. pop (); 156 157 // retrieve the end operator 158 char Opt = OperatorStack. pop (); 159 160 // binary operator calculation. 161 float Ret = Calculate (Operand1, Operand2, Opt); 162 OperandStack. Push (Ret); 163} 164 165 return OperandStack. Peek (); 166}View Code