Idea:
The whole process is to traverse the string of the required operation input once
Each time an element is judged and operated, there are two stacks (a number stack and a symbol stack)
(1) If it is a number, put it on the number stack, and then continue to operate on the element in the next string
Here are some operations on parentheses:
If it is an open parenthesis, enter the symbol stack, and then continue to operate on the elements in the next string
If it is a right parenthesis, let the element at the top of the symbol stack out of the stack, let the two elements at the top of the digital stack and the top of the secondary stack out of the stack for operation, and put the operation results into the digital stack. This operation will be repeated until the top of the symbol stack is an left parenthesis. When the left parenthesis is met, it will be out of the symbol stack, and continue to operate the elements in the next string
(2) In the case of symbols:
If the symbol stack is empty, enter it directly into the symbol stack
If the priority of the symbol at the top of the symbol stack is greater than the element in the string currently being operated, the symbol at the top of the symbol stack is taken out of the stack, and the two elements at the top of the digital stack and the top of the secondary stack are taken out of the stack. After operation, the result is put into the digital stack
If the priority of the symbol at the top of the symbol stack is less than the element in the string currently being operated on, it is put into the symbol stack
(3) When all the elements in the string are traversed, if there are still elements in the symbol stack, continue to push out one element from the symbol stack and two elements from the digital stack. After calculation, put the result into the digital stack and cycle this operation until the symbol stack is empty
The specific codes are as follows:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define n 50 //Digital stack typedef struct nodeFirst{ double a[n]; int size;// Indicates the number of elements contained in the stack } stackFirst; //Symbol stack typedef struct nodeSecond{ char a[n]; int size; } stackSecond; //Digital stack out of stack double pop(stackFirst *p) { if (p -> size == 0) //printf("empty stack"); return 0; else { --(p -> size); return p -> a[p -> size]; } } //Symbol stack out of stack char popSecond(stackSecond *p) { if (p -> size == 0) return 0; else { --(p -> size); return p -> a[p -> size]; } } //Returns the top element of the digital stack double top(stackFirst *p) { if (p -> size == 0) return 0;//Output 0 means null else { return p -> a[p -> size - 1]; } } //Returns the top element of the symbol stack char topSecond(stackSecond *p) { if (p -> size == 0) return 0;//Output 0 means null else { return p -> a[p -> size - 1]; } } //Empty the number stack int empty(stackFirst *p) { return p -> size == 0; } //Empty symbol stack int emptySecond(stackSecond *p) { return p -> size == 0; } //Digital stack void push(stackFirst *p, double b) { p -> a[p -> size] = b; ++p -> size; } //Symbol stack void pushSecond(stackSecond *p, char b) { p -> a[p -> size] = b; ++p -> size; } //Compare symbol priority int compare(char str) { if (str == '+' || str == '-') { return 1; } else if (str == '*' || str == '/') { return 2; } else { return 0; } } //calculation double counter(double x, double y, char str) { double ans = 0.0; if (str == '-') { ans = x - y; } else if (str == '+') { ans = x + y; } else if (str == '*') { ans = x * y; } else { ans = x / y; } return ans; } int main(void) { //Digital stack stackFirst *first; first = (stackFirst *) malloc(sizeof(stackFirst)); first -> size = 0; //Symbol stack stackSecond *second; second = (stackSecond *) malloc(sizeof(stackSecond)); second -> size = 0; char a[100]; printf("Please enter the arithmetic expression to be evaluated:\n"); scanf("%s", a); int length = (int)strlen(a); //Add '#' after the formula entered by the user a[length] = '#'; length = length + 1; int i = 0; double x = 0; //Out of stack symbols for calculation char strtest; //Number out of stack for calculation double numFirst, numSecond; //Used to save the current calculation results double res; while (a[i] != '#') { x = 0; //If it's a number, put it on the number stack if (a[i] >= '0' && a[i] <= '9') { while (a[i] >= '0' && a[i] <= '9') { x *= 10; x += a[i++] - '0'; } //The calculation is decimal if (a[i] == '.') { double d = 0.1; ++i; while (a[i] >= '0' && a[i] <= '9') { x += ((a[i] - '0') * d); d *= 0.1; ++i; } } //Digital stack push(first, x); continue; } //If it is a symbol and the symbol stack is empty, the symbol is directly entered into the symbol stack if (second -> size == 0 && (a[i] == '+' || a[i] == '-' || a[i] == '*' || a[i] == '/' || a[i] == '(' || a[i] == ')')) { pushSecond(second, a[i]); ++i; continue; } //If it is an open bracket, it is directly put on the stack if (a[i] == '(') { pushSecond(second, a[i]); ++i; continue; } //If it is a right parenthesis, loop out the symbols in the symbol stack, participate in the operation with the two numbers in the number stack, and then enter the number stack until it encounters the left parenthesis if (a[i] == ')') { while (topSecond(second) != '(') { strtest = popSecond(second); numFirst = pop(first); numSecond = pop(first); res = counter(numSecond, numFirst, strtest); //The calculation result is put into the data stack push(first, res); } //Left bracket out of stack popSecond(second); ++i; continue; } //The last case is to enter the symbol stack while (compare(a[i]) <= compare(topSecond(second))) { strtest = popSecond(second); numFirst = pop(first); numSecond = pop(first); res = counter(numSecond, numFirst, strtest); //The calculation result is put into the data stack push(first, res); } //Input symbol stack pushSecond(second, a[i]); ++i; } //If the symbol stack is not empty while (second -> size > 0) { strtest = popSecond(second); numFirst = pop(first); numSecond = pop(first); res = counter(numSecond, numFirst, strtest); //The calculation result is put into the data stack push(first, res); } //Output final calculation results printf("%lf\n", top(first)); return 0; }
Final operation result: For example: Input: 4.2+5*(2.1+(1+2)) Output: 29.700000