The infix expression is our favorite form: the binary operator is in the middle, and its two operands are on both sides:
A + B * C + (D * E + F) * g
Suffix and prefix expression. As the name implies, operators are placed before or after each other. Note that no parentheses exist. manual conversion is to add parentheses in the order of operation, then place the operators before or after the brackets, for example:
(A + (B * C) + (D * E) + F) * g ))
There are:
+ (A * (B c) * (+ (* (D E) f) g ))
There are:
(A (B C) *) + (d e) * f) + G) *) +
Remove the parentheses. The prefix expression is:
++ A * BC * + * defg
Suffix expression:
ABC * + de * F + G * +
Obviously, the difference between them and the fix expression is that their priority information is contained in the formula and no extra brackets are required. The evaluate method is. For prefix expressions:
From the right to the left scan type, start from the first character on the right, if the current character is a number, it is recorded until the end of the number string. If it is an operator, calculate the two "number strings" closest to the right, and use them as a new "number string" and record them. When the leftmost side of the expression is scanned, the value of the final operation is the value of the expression.
For suffix expressions, the principle is the same, but the direction of the read expression is the opposite, scanning the expression from left to right.
Both methods are easily implemented using stacks. Therefore, computers usually use this method to calculate
Expression Tree: organizes an expression into a tree. Operators are used as root nodes and operands are used as leaves to recursively organize them. It is easy to know that you can obtain the prefix and suffix expressions after traversing the Expression Tree.
Conversion between an infix expression and a suffix expression
Stack is easy to implement
1. if you encounter a right bracket, the elements in the stack will pop up until you encounter a left bracket.
2. When an operator is encountered, it is compared with the current operator on the top of the stack. If the value is higher than the top of the stack, it is written into the stack. Otherwise, the output stack will be given a lower priority than the top-of-stack operator. For left brackets, directly go to the stack
3. When an operand is encountered, it is directly written into the suffix expression.
The implementation is as follows:
int infix_to_postfix(char *in, char *post, Stack* st){int infix_len = strlen(in), i, j;for (i = 0, j = 0; i < infix_len; i++){if (isdigit(in[i]) || isalpha(in[i])) {post[j++] = in[i];}else if (in[i] == '(') {push(&st, in[i]);}else if (in[i] == ')') {while (check_top(st) != '('){post[j++] = pop(&st);}pop(&st);}else {//pop if the operator's priority is less or equal than the topwhile (!isempty_stack(st) && check_top(st) != '(' && get_priority(in[i]) <= get_priority(check_top(st))){post[j++] = pop(&st);}push(&st, in[i]);}}while (!isempty_stack(st)){post[j++] = pop(&st);}}
Transformation of infix and prefix expressions
It is similar to infix and suffix, but it is read in reverse order. And after the end, output in reverse order:
1. If left brackets are met, the elements in the stack will pop up until the right brackets are met.
2. When an operator is encountered, it is compared with the current operator on the top of the stack. If the value is higher than the top of the stack, it is written into the stack. Otherwise, the top of the stack operator has a higher priority than the top of the stack operator (including equal ). For right brackets, directly go to the stack
3. When an operand is encountered, it is directly written into the prefix expression.
The implementation is as follows:
int infix_to_prefix(char *in, char *pre, Stack* st){reverse_str(in);int infix_len = strlen(in), i, j;for (i = 0, j = 0; i < infix_len; i++){if (isdigit(in[i]) || isalpha(in[i])) {pre[j++] = in[i];}else if (in[i] == ')') {push(&st, in[i]);}else if (in[i] == '(') {while (check_top(st) != ')'){pre[j++] = pop(&st);}pop(&st);}else {//pop if the operator's priority is less than the topwhile (!isempty_stack(st) && check_top(st) != ')' && get_priority(in[i]) < get_priority(check_top(st))){pre[j++] = pop(&st);}push(&st, in[i]);}}while (!isempty_stack(st)){pre[j++] = pop(&st);}reverse_str(pre);}
The way to generate an expression tree using a suffix expression is similar to the way to calculate a suffix expression: scanning from left to right, reading the operand generates a leaf node, reading each operator, two out of the stack, and the operator acts as the parent node at the same time, combine them into a tree, and then the parent node goes to the stack, and so on. The implementation is as follows:
Bintree_node* postfix_to_tree (char *s, Stack* st){char *p;int len = strlen(s), i;Bintree_node * p_node, *op1, *op2;for (p = s, i = 0; i < len; i++){//while (*(p+i) == ' ') i++;if (isdigit(*(p+i))) {p_node = (Bintree_node*)malloc(sizeof(Bintree_node));p_node -> ele = *(p+i);p_node -> left = NULL;p_node -> right = NULL;push(&st, p_node);}else if (*(p+i) == '+' || *(p+i) == '*' || *(p+i) == '/' || *(p+i) == '-') {op1 = pop(&st);op2 = pop(&st);p_node = (Bintree_node*)malloc(sizeof(Bintree_node));p_node -> ele = *(p+i);p_node -> left = op2;p_node -> right = op1;push(&st, p_node);}}return pop(&st);}