C language: expression evaluate implementation (including addition, subtraction, multiplication, and division of parentheses)
This question is not difficult, but when you carefully compile the code, you still need to consider a lot of details, so you cannot just stay at the level of understanding, if you do not practice it, you will never know whether you have mastered it. Come on!
The evaluate of the previous expression does not include the brackets operation. Now, the improved code and source code are pasted on the above, so that you can easily review the code later.
I. Parentheses are not included
# Include
# Include
# Include
# Include
# Include
# Define STACK_INIT_SIZE 100 using namespace std; typedef struct {char date [STACK_INIT_SIZE]; int top;} OptrStack; // operator struct typedef struct {double date [STACK_INIT_SIZE]; int top ;} opndStack; // operand struct // operator-related operations OptrStack * Init_OptrStack (); // sets the stack null int Empty_OptrStack (OptrStack * s ); // judge the empty stack int Push_OptrStack (OptrStack * s, char x); // The inbound stack (Note: Check whether the stack is full) char Pop_OptrStack (OptrStack * s, char x ); // output stack (Note: Check whether the stack is empty) Char GetTop_OptrStack (OptrStack * s, char x); // gets the top element of the stack and first determines whether to perform null // operations on OpndStack * Init_OpndStack (); // set the stack to an empty int Empty_OpndStack (OpndStack * t); // judge the empty stack int Push_OpndStack (OpndStack * t, double y); // inbound stack (note: determine whether the stack is full.) double Pop_OpndStack (OpndStack * t, double y); // output stack (Note: whether the stack is empty) double GetTop_OpndStack (OpndStack * t, double y ); // take the top element of the stack // evaluate the expression void Error (char * s); // The Error handling function int Judge_optr (char ch); // used to determine whether the character ch is an operator Int Operate (int a, int B, char top); // calculate the current value and return the value void Jsbds_operate (char str []); // read the value of a simple arithmetic expression // operator function implementation part OptrStack * Init_OptrStack () {OptrStack * s; s = (OptrStack *) malloc (sizeof (OptrStack )); s-> top =-1; return s;} int Empty_OptrStack (OptrStack * s) // judge empty stack {if (s-> top! =-1) return 1; else return 0;} int Push_OptrStack (OptrStack * s, char x) // inbound stack (Note: Check whether the stack is full) {if (s-> top = (STACK_INIT_SIZE-1) {return 0;} else s-> date [++ s-> top] = x; return 1 ;} char Pop_OptrStack (OptrStack * s, char x) // output stack (Note: Determine whether the stack is empty) {if (! Empty_OptrStack (s) {return 0;} else x = s-> date [s-> top]; s-> top --; return x ;} char GetTop_OptrStack (OptrStack * s, char x) // gets the top element of the stack and first returns NULL {if (! Empty_OptrStack (s) {return 0;} else x = s-> date [s-> top]; return x;} // part of OpndStack * Init_OpndStack () // stack empty {OpndStack * t; t = (OpndStack *) malloc (sizeof (OpndStack); t-> top =-1; return t ;} int Empty_OpndStack (OpndStack * t) // empty stack determination {if (t-> top! =-1) return 1; else return 0;} int Push_OpndStack (OpndStack * t, double y) // inbound stack (Note: Check whether the stack is full) {if (t-> top = (STACK_INIT_SIZE-1) {return 0;} else t-> date [++ t-> top] = y; return 1 ;} double Pop_OpndStack (OpndStack * t, double y) // output stack (Note: Determine whether the stack is empty) {if (! Empty_OpndStack (t) {return 0;} else y = t-> date [t-> top]; t-> top --; return y ;} double GetTop_OpndStack (OpndStack * t, double y) // gets the top element of the stack {if (! Empty_OpndStack (t) {return 0;} y = t-> date [t-> top]; return y ;} // void Error (char * s) implemented by the expression evaluate function // Error handling function {std: cout <s <endl; exit (1 );} int Judge_optr (char top) // used to determine whether the character ch is an operator {int x; // cout <top <"test" <endl; switch (top) {case '+': case '-': x = 1; break; case '*': case '/': x = 2; break;} return x ;} double Operate (double B, double a, char top) // calculate the current value and return the value {double c = 0; switch (top) {case '+': c = B + a; break; case '-': c = B-a; break; case '*': c = B * a; break; case '/': if (a = 0) {printf ("the denominator is zero! \ N "); return 0;} else c = B/a; break; default: printf (" the entered character is invalid! \ N "); break;} return c;} void Jsbds_operate (char str []) // read a simple arithmetic expression, return the calculation result to the main function {OptrStack * optr = Init_OptrStack (); // initialize the operator stack OpndStack * opnd = Init_OpndStack (); // initialize the operand stack int I, j; // I, j is a cyclic variable. a and B receive the double f element from the stack of the operand stack. // The receiving value converts the number of characters to the value of double a = 0; double B = 0; double c = 0; char d [100]; // store the consecutive 'number' char top = 0; // receives the element for (I = 0; str [I]; I ++) from the operator stack) // Add the elements in the string to the stack in sequence {switch (str [I]) {case '+': case '-':/* first judge the priority of the current operator and the top element of the operator stack. If it is higher than the top element of the stack, it is written into the stack; if the value is smaller than the top element of the stack, two numbers are generated from the operand stack in sequence. The top element of the operator stack is output from the stack, and then the two numbers are obtained from the operand stack, press the operator operation from the operator stack, press the result into the operand stack, and then press the current operator into the operator stack. */If (! Empty_OptrStack (optr) // when the operator stack is empty, the pressure stack is saved {Push_OptrStack (optr, str [I]);} else {a = Pop_OpndStack (opnd, ); // receives the Element B = Pop_OpndStack (opnd, B) from the operand stack; // receives the element top = Pop_OptrStack (optr, top) from the operand stack ); // receives the elements c = Operate (B, a, top) from the operator stack; Push_OpndStack (opnd, c ); // push the calculated value to Push_OptrStack (optr, str [I]);} break; case '*': case'/': if ((! Empty_OptrStack (optr) | (Judge_optr (str [I])> Judge_optr (GetTop_OptrStack (optr, top )))) {// when the operator stack is empty or the operator's priority is higher than the top element of the stack, the Push_OptrStack (optr, str [I]) is saved in the stack;} else {a = Pop_OpndStack (opnd, a); // receives the elements B = Pop_OpndStack (opnd, B) from the operand stack ); // receives top = Pop_OptrStack (optr, top) elements from the stack of the operations; // receives the c = Operate (B,, top); Push_OpndStack (opnd, c); // push the calculated value to Push_OptrStack (optr, str [I]);} case '\ 0': break; default: j = 0; do {d [j ++] = str [I]; I ++ ;} while (str [I]> = '0' & str [I] <= '9 '); // one or more numeric characters d [j] = '\ 0' can be saved; // concatenates multiple consecutive numeric characters into a string I --; f = atof (d); // call the database function atoi () to convert the number of characters to the floating point Push_OpndStack (opnd, f ); // press the converted number into the break stack. }}while (Empty_OptrStack (optr) // when the operator stack is not empty, run {a = Pop_OpndStack (opnd, a); // receives the Element B = Pop_OpndStack (opnd, B) from the operand stack; // receives the element top = Pop_OptrStack (optr, top); // receives the elements c = Operate (B, a, top) from the operator stack; Push_OpndStack (opnd, c ); // press the calculated value into the operand stack} cout <"the calculation result of this expression is:"; std: cout <GetTop_OpndStack (opnd, c) <endl; // print the elements in the operand stack (that is, the final result of the expression)} int main () {char str [100]; std :: cout <"Enter the arithmetic expression (function: +,-, *,/)" <endl; cin> str; Jsbds_operate (str); return 0 ;}
Ii. Include parentheses (paste and modify)
Int Judge_optr (char top) // used to determine whether the character ch is an operator {int x; // cout <top <"test" <endl; switch (top) {case '(': x = 0; break; case '+': case '-': x = 1; break; case '*': case '/': x = 2; break; case ')': x = 3; break;} return x;} double Operate (double B, double a, char top) // calculate the current value and return the value {double c = 0; switch (top) {case '+': c = B + a; break; case '-': c = B-a; break; case '*': c = B * a; break; case '/': if (a = 0) {printf ("The denominator is zero! \ N "); return 0;} elsec = B/a; break; default: printf (" the entered character is invalid! \ N "); break;} return c;} void Jsbds_operate (char str []) // read a simple arithmetic expression, return the calculation result to the main function {OptrStack * optr = Init_OptrStack (); // initialize the operator stack OpndStack * opnd = Init_OpndStack (); // initialize the operand stack int I, j; // I, j is a cyclic variable. a and B receive the double f element from the stack of the operand stack. // The receiving value converts the number of characters to the value of double a = 0; double B = 0; double c = 0; char d [100]; // store the consecutive 'number' char top = 0; // receives the element for (I = 0; str [I]; I ++) from the operator stack) // Add the elements in the string to the stack in sequence {switch (str [I]) {case '(': Case '+': case '-':/* first judge the priority of the current operator and the top element of the operator stack. If it is higher than the top element of the stack, it is imported into the stack; if the value is smaller than the top element of the stack, two numbers are generated from the operand stack in sequence. The top element of the operator stack is output from the stack, and then the two numbers are obtained from the operand stack, press the operator operation from the operator stack, press the result into the operand stack, and then press the current operator into the operator stack. */If ((! Empty_OptrStack (optr) | (Judge_optr (str [I])> Judge_optr (GetTop_OptrStack (optr, top) | (str [I] = '(')) // when the operator stack is empty, the pressure stack stores {Push_OptrStack (optr, str [I]);} else {a = Pop_OpndStack (opnd, ); // receives the Element B = Pop_OpndStack (opnd, B) from the operand stack; // receives the element top = Pop_OptrStack (optr, top) from the operand stack ); // receives the elements c = Operate (B, a, top) from the operator stack; Push_OpndStack (opnd, c ); // push the calculated value to Push_OptrStack (optr, str [I]);} break; case '*': c Ase '/': if ((! Empty_OptrStack (optr) | (Judge_optr (str [I])> Judge_optr (GetTop_OptrStack (optr, top) | (str [I] = '(')) {// when the operator stack is empty or the operator's priority is higher than the top element of the stack, the Push_OptrStack (optr, str [I]) is saved in the stack;} else {a = Pop_OpndStack (opnd, a); // receives the elements B = Pop_OpndStack (opnd, B) from the operand stack ); // receives top = Pop_OptrStack (optr, top) elements from the stack of the operations; // receives the c = Operate (B,, top); Push_OpndStack (opnd, c); // push the calculated value to Push_OptrStack (optr, str [I]);} break; case ')': push_OptrStack (optr, str [I]); break; case '\ 0': break; default: j = 0; do {d [j ++] = str [I]; I ++;} while (str [I]> = '0' & str [I] <= '9 '); // one or more numeric characters d [j] = '\ 0' can be saved; // concatenates multiple consecutive numeric characters into a string I --; f = atof (d); // call the database function atoi () to convert the number of characters to the floating point Push_OpndStack (opnd, f ); // press the converted number into the break stack. }}while (Empty_OptrStack (optr )) // when the operator stack is not empty, execute {if (GetTop_OptrStack (optr, top) = ') | (GetTop_OptrStack (optr, top) = '(') {top = Pop_OptrStack (optr, top);} else {a = Pop_OpndStack (opnd, ); // receives the Element B = Pop_OpndStack (opnd, B) from the operand stack; // receives the element top = Pop_OptrStack (optr, top) from the operand stack ); // receives the elements c = Operate (B, a, top) from the operator stack; Push_OpndStack (opnd, c ); // press the calculated value into the operand stack.} cout <"the result of this expression is:"; std: cout <GetTop_OpndStack (opnd, c) <endl; // print the elements in the operand stack (that is, the final result of the expression}