crecursionmathclionbrackets

How calculate an arithmetic expression using recursion, having problem with brackets


Im trying to write a code that will take mathematical input from the user [example: (1+2x3), (2x(3+4)), (2x(3+4)-(6/2))...] and print the result, using recursion.

I was able to come up with a code that works for expressions like the in the example however, it seems that expression containing too many brackets right beside each other [example :(2x((3+4)-(6/2))), ((2x3+4)-(6/2))] are giving me wrong answers.

I am not allowed to use array for this so instead I check every character individually. Also the actual order of operation is not relevant, all calculation need to be made from left to right, and the only thing that matters is brackets. For example (1+2x3) = 9, and not 7. (1+(2x3)) = 7 however. The basic expression must start with "(" and end with ")". Also I can assume all the numbers will be from 0-9.

This is the main function. Currently I'm assuming that the expression is built in a valid way, and I start the recursion by making sure the first char is "(" and then put 0 as a default of sort, so the nptnum is already the next char when starting.

The "1" in the middle is used for bracket counting, however I didn't find a use for this in the code so far.

int main() {
    printf("enter an expression:\n") ;
    char nptnum ;
    int num = 0 ;

    scanf(" %c", &nptnum) ;
    if(nptnum == '('){
        scanf(" %c", &nptnum) ;
        num = elevator(0, 1, nptnum) ;
    }
    printf("this is num %d\n", num) ;

return 0 ;
}

This is the recursive code. Again, so far the bracketcounter is not used in a meaningful way.

The idea is to:

  1. When reaching ( call the function.
  2. Calculate everything inside until reaching ).
  3. return that sum.
  4. Repeat
int elevator(int number, int brackets, char nptnum) {
    int bracketcount = brackets ;
    int num ;
    char operand ;

    num = number ;
   
    if(nptnum >= '0' && nptnum <= '9') {
        num = (nptnum - 48) ;
        scanf(" %c", &nptnum) ;
    }

    //if the first character is ) that means there is no calculation to be made
    if(nptnum == ')'){
        bracketcount--;
        return num ;
    }

    //get the operand  
    if(nptnum == '+' || nptnum == '-' || nptnum == '*' || nptnum == '/') {
        operand = nptnum ;
        scanf(" %c", &nptnum) ;
    }

    int num2 ;
    //recursion in case of new brackets
    if(nptnum == '(') {
        while(nptnum == '('){
            bracketcount++ ;
            scanf(" %c", &nptnum) ;
        }
        num2 = elevator(0, bracketcount, nptnum) ;
        scanf(" %c", &nptnum) ;

    } else if (nptnum >= '0' && nptnum <= '9') {
        num2 = (nptnum - 48) ;
        scanf(" %c", &nptnum) ;
        printf("third char: %c\n", nptnum) ;

    }
    int sum ;
    printf("num is: %d, num2 is: %d, op is : %c\n", num, num2, operand) ;

    //operator is a simple arithmetic calculation function 
    sum = operator(num, num2, operand) ;

    printf("op result %d\n", sum) ;
    printf("before check %c and bracket %d\n", nptnum, bracketcount) ;
    //a recursive call for the rest of the expression when there are no new brackets
    if(nptnum != ')'){
        bracketcount-- ;
        sum = elevator(sum, bracketcount, nptnum) ;
        printf("this is sum: %d\n", sum) ;
    }
    return sum ;
}

operator function

int operator (int num1, int num2 , char op) {
    switch (op) {
        case '+' : {
            return (num1 + num2) ;
            break ;
        }
        case '-' : {
            return num1 - num2 ;
            break ;
        }
        case '*' : {
            return num1 * num2 ;
            break ;
        }
        case '/' : {
            return num1 / num2 ;
            break ;
        }
    }
}

Solution

  • Thanks for everyone that helped and explained what I didn't understand! I was able to write code that does what I need to, pretty sure it does basically what people here said I should do (perhaps a bit messy).

    I will explain once more what this code does. It takes an expression in the form of (1+2*3(6/2)) for example and print the final result of the calculation.

    It does the calculation from left to right and ignore normal order of operations rules, but still give priority to expressions in brackets.

    #include <stdio.h>
    
    int evaluator() ;
    int operator (int num1, int num2 , char op) ;
    
    int main() {
        printf("enter an expression:\n") ;
        char npt = scanf(" %c", &npt) ;
        int num = 0 ;
        num = evaluator() ;
        printf("this is num %d\n", num) ;
    
    return 0 ;
    }
    
    int elevator() {
        char npt, op ;
        int number = 0, number2 = 0, number3 = 0, count = 0;
        if(npt != ')') {
            scanf("%c", &npt) ;
        }
    
        while (npt != ')') {
            if(npt == '(') {
                number = evaluator() ;
                scanf(" %c", &npt) ;
            } else if(npt >= '0' && npt <= '9') {
                number = npt-'0';         
                scanf(" %c", &npt) ;
            }
    
            if(npt == '+' || npt == '-' || npt == '*' || npt == '/') {
                op = npt ;           
                scanf(" %c", &npt) ;
            }
    
            if(npt== '(') {
                number3 = evaluator() ;            
                scanf(" %c", &npt) ;
            }
            else if (npt >= '0' && npt <= '9') {
                number3 = npt - '0';
                scanf(" %c", &npt) ;            
            }
                number = operator(number, number3, op) ;           
        }
        return number ;
    }
    
    int operator (int num1, int num2 , char op) {
        switch (op) {
            case '+' : {
                return (num1 + num2) ;
                break ;
            }
            case '-' : {
                return num1 - num2 ;
                break ;
            }
            case '*' : {
                return num1 * num2 ;
                break ;
            }
            case '/' : {
                return num1 / num2 ;
                break ;
            }
        }
    
    }