If it is a simple addition or subtraction operation expression, it is very simple to process the expression's first character in sequence.
However, for the four arithmetic operations, there are parentheses and multiplication and division first, and then addition and subtraction make the expression processing more responsible.
In 1950s, Jan Lukasiewicz, a Polish logologist, invented a suffix expression that does not require parentheses.
For example
char sInput[]="9+(3-1)*3+8/2"; //output 931-3*+82/+
After being converted to-3 × + 82/+, each character is traversed from the beginning. When an operator is encountered, the first two numbers of the operator are operated, for example, if you encounter the first "-", then perform "3-1 = 2", and then put the calculation result back to "923x + 82/+ ", then, when we encounter "X", in the calculation of "2 × 3 = 6", we put 6 back into "96 + 82/+", and so on.
It is called a suffix expression because all operators appear after numbers. If the stack data structure is used, it is easy to calculate the final result.
Another problem is how to convert the "infix expression" that we are familiar with into a "suffix expression"
Rule: traverse each number and symbol of the infix expression from left to right. If it is a number, it is output, which is a part of the suffix expression. If it is a symbol, it judges its priority with the symbol on the top of the stack, if it is a right brace or the priority is lower than the top finding symbol (multiplication, division, plus or minus), the top elements of the stack are sequentially located and output, and the current symbol is added to the stack until the suffix expression is finally output.
For specific implementation ideas, refer to here
The following is an idea implemented in C language, because I also temporarily learned C language for 2 hours (tan xx textbook I learned in the university, I forgot it !!), The content is not rigorous, but it provides a reference for C language learners.
Speaking out of question, it is very easy to implement with other glue languages, but I think using C language to program the memory with micro-operations and using various clever algorithms is the most appealing, most code farmers, including me, are actually a demand implementation salesman. They cannot be called code craftsmen at all!
The Code of stack data structure is based on others. Although there are many online data structures, it is concise enough.
Test. h defines the data structure and operation functions of the stack. (If you do not care about the stack implementation method, you can skip test. h and jump to here)
# Include "stdio. H "# include" stdlib. H "# include" math. H "# include" time. H "# define OK 1 # define error 0 # define true 1 # define false 0 # define maxsize 20/* Initial bucket allocation */typedef int status; typedef char selemtype; /* The selemtype type depends on the actual situation. Here it is assumed to be int * // * sequence stack structure */typedef struct {selemtype data [maxsize]; int top; /* for top stack pointer */} sqstack; Status visit (selemtype c) {printf ("% d", c); Return OK ;} /* construct an empty stack S */status initstack (sqstack * s) {/* s. data = (selemtype *) malloc (maxsize * sizeof (selemtype); */S-> Top =-1; Return OK ;} /* Set S to empty stack */status clearstack (sqstack * s) {S-> Top =-1; Return OK;}/* if Stack S is empty stack, true is returned. Otherwise, false */status stackempty (sqstack s) {If (S. top =-1) return true; else return false;}/* Number of elements returned by s, that is, the stack length */INT stacklength (sqstack s) {return S. top + 1;}/* If the stack is not empty, use e to return the top element of S stack, and Return OK; otherwise, Error */status gettop (sqstack S, selemtype * E) is returned) {If (S. top =-1) Return Error; else * E = S. data [S. top]; Return OK;}/* insert element e as the new top stack element */status push (sqstack * s, selemtype E) {If (S-> Top = maxsize-1)/* Full stack */{return error;} s-> top ++; /* Add the top pointer of the stack */S-> data [S-> top] = E;/* assign the new inserted element to the top space of the stack */Return OK ;} /* If the stack is not empty, delete the top element of S stack, return its value with E, and Return OK; otherwise, Return Error */status POP (sqstack * s, selemtype * E) {If (S-> Top =-1) Return Error; * E = s-> data [S-> top]; /* the top element of the stack to be deleted is assigned to E */S-> top --;/* the top pointer of the stack minus one */Return OK ;} /* display each element in the stack from the bottom of the stack to the top of the stack */status stacktraverse (sqstack s) {int I; I = 0; while (I <= S. top) {visit (S. data [I ++]);} printf ("\ n"); Return OK;} status stackout (sqstack s) {int I; I = S. top; while (I>-1) {printf ("% C \ n", S. data [I --]);} printf ("\ n"); Return OK ;}
Code for converting an infix expression to a suffix expression in test. c
#include"test.h"/* is number ? */int isNumber (char i){ if(i<58 && i>47){ return 1; }else{ return 0; }}/* is logic operator ? */int isLogic (char i){ if(i == 42 || i == 43 || i == 45 || i == 47) { return 1; }else{ return 0; }}/* get logic symbol prior*/int prior (char i){ switch(i) { case ‘-‘: return 1; case ‘+‘: return 1; case ‘/‘: return 2; case ‘*‘: return 2; }}int main(){ char sInput[]="9+(3-1)*3+8/2"; //output 931-3*+82/+int i = 0; SqStack myStack; InitStack(&myStack); printf("start\n"); //todo: other way to loop char array while(sInput[i] != ‘\0‘){ char cCur = sInput[i]; if(isNumber(cCur)){ printf("%c\n",cCur); }else{ if(cCur == 41) // 41 is ‘)‘ { char cB; cB = ‘1‘; while(cB != 40) // 40 is ‘(‘ { if(cB != ‘1‘){ printf("%c\n",cB); } Pop(&myStack,&cB); } }else{ //none num and not ‘)‘ if(isLogic(cCur) && isLogic(myStack.data[myStack.top])) { if(prior(cCur) <= prior(myStack.data[myStack.top])) { while(myStack.top > -1) { char cE; Pop(&myStack,&cE); printf("%c\n",cE); } Push(&myStack,cCur); }else{ Push(&myStack,cCur); } }else{ //printf("%c\n",cCur); Push(&myStack,cCur); } } } i++; } //printf("top:%i\n", myStack.top); StackOut(myStack); printf("\nend\n"); return 0;}
The implementation logic is to directly output a number, that is, the first half of the while.
If you encounter a non-number, there are two situations:
1. If it is ')', go to the stack to play the stack and output it in sequence until you find '(this left bracket does not need to be output ).
2. If it is an operator (+-*/), you can see what the top stack is.
A. If it is a number, press the operator on the stack.
B. if it is also an operator, compare the priority of the current operator and the stack top operator (*/priority is greater than +-). If the current operator has a higher priority, press the operator directly to the stack. If it is less than or equal to, all the elements in the stack will be output through the stack (there will be no lower operators than the +-operator ), then press the current operator on the stack.
3. What if the entire expression traversal is complete? Of course, it is to spit out all the items in the stack !!
The code is successfully compiled in the GCC 4.8.2 of ubuntu14 and the final result is output.
start931-3*+82/+end
After being converted to an infix expression, you can continue to use the stack method to calculate the final result.
Haha, do you think the implementation of the four arithmetic operations at the bottom of the C language is very interesting ?????
What, the code is too rough? Sorry, I actually wrote PHP :)
Use reverse Polish (reverse Polish notation, RPN) Suffix expression to calculate four arithmetic expressions