I. Question

◆ 3.21 ③ assume that the expression is represented by a single letter variable and a pair of four eyes

Operator structure. Try to write an algorithm that combines a common writing form

And the correct expression is converted to the inverse polish type.

Implement the following functions:

Char * RPExpression (char * e );

/* Returns the inverse polish expression of expression e */

Stack is an implemented Stack.

Available types and functions:

Typedef char SElemType; // element type of Stack

Status InitStack (Stack & s );

Status Push (Stack & s, SElemType e );

Status Pop (Stack & s, SElemType & e );

Status StackEmpty (Stack s );

SElemType Top (Stack s );

Bytes -------------------------------------------------------------------------------------------------

Ii. Ideas

The first thing to do when you get the question is**Understand what the question is about.**Obviously, the keyword in the question is "inverse Polish style". First, we need to understand this concept.

The so-called**Reverse Polish notation**(**Reverse Polish notation**,**RPN**, Or**Inverse Polish notation**), Is a mathematical expression. In the inverse Polish notation, all operators are placed behind the operands. Therefore**Suffix notation**. Brackets are not required to mark the operator priority in the inverse Polish notation. (From Wikipedia)

For example, a mathematical expression a + B is an infix expression, and a suffix expression is AB +. For another complex example, the inverse Polish formula of the infix expression (a + B) * c-(a + B)/e is AB + c * AB + e /-.

After figuring out the concepts and the requirements of the questions, we need to write algorithms. So what is the idea of converting an expression into an inverse Polish algorithm?

(1) first, two stacks need to be allocated. Stack s1 is used for temporary storage operators (including an ending symbol). This operator follows the principle of higher priority to the top of the stack; stack s2 is used to input the inverse Polish formula. For convenience, stack s1 should first put an operator with the lowest priority, which is assumed to be '#' here '#';

(2) read character x from the left end of the infix one by one and perform the following steps in sequence:

1. If x is the operand, the complete number of operations is analyzed (for convenience, replace digits with letters), and x is directly pushed to stack s2;

2. If x is an operator, we will discuss the situation as follows:

If x is '(', it is directly pushed into Stack s1;

If x is ')', the operator '(') closest to the top of stack s1 is pushed to stack s2 one by one and then discarded '(';

If x is an operator other than '(' and ')', it is further discussed as follows:

If the top element of the current stack s1 is '(', x is directly pushed to the stack s1;

If the top element of the current stack s1 is not '(', compare x with the top element of the stack s1. If x has a higher priority than the top operator of the stack s1, then, x is directly pushed into Stack s1. Otherwise, the stack top operator of stack s1 pops up and is pushed into Stack s2 until the stack top operator priority of stack s1 is lower than (not including equal to) x, or the stack top operator of stack s2 is '(', then press x into Stack s1;

(3) After loading (2), check whether stack s1 is empty. If not, then, the elements in the stack pop up and press them into Stack s2 (not including '#');

(4) After completing the preceding steps, stack s2 outputs the result in a reverse Polish format. However, stack s2 should perform reverse processing because the first character of the expression is located at the bottom of the stack;

Bytes -------------------------------------------------------------------------------------------------

Iii. Code (C/C ++) C code

1 char * RPExpression (char * e) 2/* return the reverse polish expression e */3 {4 // stack s1 is used to store operators, stack s2 is used to store reverse-Polish 5 Stack s1, s2; 6 InitStack (s1); 7 InitStack (s2 ); 8 9 // assume that the character '#' is the operator with the lowest operation level and is pushed to 10 Push (s1, '#') in stack s1 ,'#'); 11 12 // p pointer is used to traverse the input string. ch is used to temporarily store characters. length is used to calculate the string length 13 char * p = e, ch; 14 int length = 0; 15 for (; * p! = '\ 0'; p ++) // access the 16 {17 switch (* p) character by character) 18 {19 // encounter '(' Then directly into the stack s120 case '(': 21 Push (s1, * p); 22 break; 23 // encounter ') 'The operator between the two closest to the top of the stack s1 '(' is sent to stack s2 one by one, and then discarded '('24 case ')': 25 while (Top (s1 )! = '(') 26 {27 Pop (s1, ch); 28 Push (s2, ch); 29} 30 Pop (s1, ch); 31 break; 32 // In case of the following operators, we will discuss the following: 33 // 1. if the top element of the current stack s1 is '(', the current operator is directly pushed into the stack s1; 34 // 2. otherwise, compare the current operator with the stack top element of stack s1. If the priority is higher than that of the stack top element, directly press it into Stack s1, 35 // otherwise, the s1 stack top element will pop up, and press it into Stack s2 until the top operator priority is lower than the current operator, and then press the current operator into Stack s1 36 case '+': 37 case '-': 38 for (ch = Top (s1); ch! = '#'; Ch = Top (s1) 39 {40 if (ch = '(') 41 {42 break; 43} 44 else45 {46 Pop (s1, ch); 47 Push (s2, ch); 48} 49} 50 Push (s1, * p); 51 length ++; 52 break; 53 case '*': 54 case '/': 55 for (ch = Top (s1); ch! = '#' & Ch! = '+' & Ch! = '-'; Ch = Top (s1) 56 {57 if (ch = '(') 58 {59 break; 60} 61 else62 {63 Pop (s1, ch); 64 Push (s2, ch); 65} 66} 67 Push (s1, * p); 68 length ++; 69 break; 70 // In case of operands, 71 default in stack s2: 72 Push (s2, * p); 73 length ++; 74} 75} 76 // if Stack s1 is not empty, the elements in the stack will pop up and press 77 while (! StackEmpty (s1) & Top (s1 )! = '#') 78 {79 Pop (s1, ch); 80 Push (s2, ch); 81} 82 // Finally, stack s2 is output and sorted into strings in reverse order; 83 char * result; 84 result = (char *) malloc (sizeof (char) * (length + 1); 85 result + = length; 86 * result = '\ 0'; 87 result --; 88 (;! StackEmpty (s2); result --) 89 {90 Pop (s2, ch); 91 * result = ch; 92} 93 ++ result; 94 return result; 95}

Bytes -------------------------------------------------------------------------------------------------

Iv. Summary

We do not know how to start when we do not understand the concept of implementing the inverse Polish algorithm at the beginning. It is not very difficult to find out the ideas. The key is to make the logic clear and be careful, it was very painful to write this code. I shared it for two days (really good ).

In addition, the meaning of the opposite Polish style in Wikipedia and Du Niang is extracted: (from Baidu)

Why is it necessary to convert a seemingly simple ordinal expression into a complex inverse polish expression? The reason is that this is simple compared to the human thinking structure. For computers, the ordinal expression is a very complex structure. Relatively, the reverse Polish style is a relatively simple and easy-to-understand structure in computer view. Because the memory structure widely used by computers is a stack-type structure, it executes the order of first-to-last-out.

Significance of the reverse Polish style: (from Wikipedia)

When there is an operator, it is calculated. Therefore, the expression is not calculated from the right to the left, but each time a part is calculated from the center. This rarely leads to operator errors in complex operations.

The stack automatically records intermediate results, which is why the reverse Polish calculator can easily evaluate any complex expression. Unlike ordinary scientific calculators, it has no limit on the complexity of expressions.

Parentheses are not required in an inverse polish expression. You only need to evaluate the values in the expression order so that the stack can automatically record intermediate results. Similarly, you do not need to specify the operator priority.

In the inverse Polish calculator, there is no equal sign key for start calculation.

The inverse Polish calculator requires a "validation" key to distinguish two adjacent operands.

The machine state is always a stack state. The stack is the number of operations that need to be performed, and there are no operators in the stack.

In education, users of the Polish calculator must understand the meaning of the expressions to be calculated.