The requirement is to remove the redundant brackets in the four arithmetic expressions. This was already encountered during the 24-point exercise in the beauty of programming. The method is simple: first convert the infix expression into a suffix expression. In this step, you can remove all the parentheses, then restore the suffix expression to an infix expression, and add necessary parentheses during restoration. There are two cases where the subexpression must be enclosed by parentheses: 1. When the subexpression has a lower priority than the root operation, the subexpression must be protected by parentheses. 2, if the root operators are minus or minus signs, because they do not meet the exchange law, in this case, if the operator priority of the Right subexpression is the same as that of the root, we also need to use parentheses to protect the right subexpression.
One review:
Algorithm for converting an infix expression to a suffix expression:
Sets an operator stack. The infix expression is processed from start to end, and is directly written into the stack in the left bracket; the operand is placed directly at the end of the suffix expression; and the operator is encountered, if the priority is higher than the priority of the elements at the top of the operator stack, the elements at the top of the stack will be taken out and placed at the end of the suffix expression until the operator priority is higher than the priority of the operator at the top of the stack; in case of right brackets, the elements at the top of the stack are constantly moved to the end of the suffix expression until the left brackets are encountered at the top of the stack and left brackets are discarded.
Experience:
1. "Programmer skills are of critical importance. For example, some combined computations need to be repeated 1 trillion times. Therefore, if we can squeeze out 1 microsecond from its inner loop, we can save 11.6 days ." (TAOCP). After you select an algorithm, you must write the code as efficient as possible. (A large number of stacks, vectors, and strings are used at the beginning. The submission score is 0.9 seconds. The algorithm is rewritten in C language and the score is 0.1 seconds ).
2. You should not only use precondition and postcondition for functions. For an algorithm, it is best to draw its flowchart and find a set of precondition and postcondition for each operation in the flowchart. This method is available in classical algorithm books, such as the loop-free technique used to prove the correctness of algorithms in TAOCP and introduction to algorithms. This method allows you to thoroughly understand algorithms. In the infix expression to suffix expression algorithm, when "the currently analyzed operator has a higher priority than the element at the top of the operator stack, It loops through the stack" and ends with an infix expression, all operators in the operator Stack are popped up to the suffix expression. medium, these two steps are used to maintain state consistency.
3. The multi-array representation of objects, single array representation of objects, allocation and release of objects, etc. described in "Implementation of pointers and objects" in "Introduction to algorithms" are extremely useful technologies. These technologies can implement dynamic data structures on arrays, which not only removes the overhead of dynamic memory allocation, but also makes it easier to implement dynamic data structures without affecting logic clarity. This method is used when the suffix-to-infix algorithm is implemented in C language. The Code is as follows:
Void parse (const char * postfix, int len) {<br/> // dynamic merge expression is required because the expression length is not fixed, therefore, if you allocate <br/> // fixed-length space for each expression, the waste should be very serious. Therefore, all expressions are stored in the result space <br/> // result can be understood as an expression stack. Start [I] indicates the start subscript of the expression I, and end [I] <br/> // indicates the end subscript, which uses semi-open and semi-closed intervals, that is, the length of the expression I is end [I]-start [I]. <Br/> // preStack is the priority stack. preStack [I] indicates the priority of the I-th expression. <Br/> // cnt indicates the number of expressions currently generated. <Br/> char result [2048]; <br/> int start [256]; <br/> int end [256], preStack [256]; <br/> int I, cnt = 0, preLeft, preRight, p, k, t; <br/> start [0] = end [0] = 0; <br/> for (I = 0; I <len; I ++) {<br/> if (isalpha (postfix [I]) {<br/> + + cnt; <br/> start [cnt] = end [cnt-1] + 5; <br/> result [start [cnt] = postfix [I]; <br/> end [cnt] = start [cnt] + 1; <br/> preStack [cnt] = 10; <br/>}else {<br/> p = pre (postfix [I]); <br/> preLeft = preStack [cnt-1]; <br/> preRight = preStack [cnt]; <br/> // brackets the left expression <br/> if (preLeft <p) {<br/> result [start [cnt-1]-1] = '('; <br/> start [cnt-1]-= 1; <br/> result [end [cnt-1] = ')'; <br/> end [cnt-1] + = 1; <br/>}< br/> // brackets the right expression <br/> if (preRight <p | <br/> (preRight = p & (postfix [I] = '-' | postfix [I] = '/'))) {<br/> result [start [cnt]-1] = '('; <br/> start [cnt]-= 1; <br/> result [end [cnt] = ')'; <br/> end [cnt] + = 1; <br/>}< br/> // merge two expressions <br/> result [end [cnt-1] = postfix [I]; <br/> end [cnt-1] + = 1; <br/> for (k = end [cnt-1], t = start [cnt]; t <end [cnt]; k ++, t ++) <br/> result [k] = result [t]; <br/> end [cnt-1] = k; <br/> cnt-= 1; <br/> preStack [cnt] = p; <br/>}< br/> for (I = 1; I <= cnt; I ++) {<br/> result [end [I] = 0; <br/> printf ("% s ", result + start [I]); <br/>}< br/> printf ("/n"); <br/>}
The following is the C code for converting an infix expression to a suffix expression:
Int Len = strlen (exp); <br/> char Postfix [256], opstack [256] = {'#'}, TMP; <br/> int Top = 0, i, pend =-1; <br/> // infix to postfix <br/> for (I = 0; I <Len; I ++) {<br/> TMP = exp [I]; <br/> If (TMP = '(') opstack [++ top] = '('; <br/> else if (isalpha (TMP) Postfix [++ pend] = TMP; <br/> else if (strchr ("+-*/", TMP )) {<br/> If (pre (TMP)> pre (opstack [Top]) {<br/> opstack [++ top] = TMP; <br/>} else {<br/> while (P Re (TMP) <= pre (opstack [Top]) {<br/> Postfix [++ pend] = opstack [top --]; <br/>}< br/> opstack [++ top] = TMP; <br/>}< br/>} else {<br/> // TMP = ')' <br/> while (opstack [Top]! = '(') {<Br/> Postfix [++ pend] = opstack [top --]; <br/>}< br/> top --; <br/>}< br/> while (opstack [Top]! = '#') {<Br/> Postfix [++ pend] = opstack [top --]; <br/>}< br/> Postfix [++ pend] = 0;