C language - four operations of stack (with decimal point and parentheses)

Posted by tommix on Sat, 02 Oct 2021 05:04:49 +0200

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

Topics: C Algorithm data structure