Home > OS >  checking balance parenthesis of an expression using stack in c
checking balance parenthesis of an expression using stack in c

Time:09-15

Application of stack

So recently came across this question where an expression is given with some parenthesis and we are told to check whether the expression is balanced or not.

This is what i have done till now, but i cant seem to pop the elements from the stack. When i pop it in the else part of the function i can seem to properly compare it.

How can i make my code work, and what is the reason for the simple comparison condition not to work?

#include <stdio.h>
#include <stdbool.h>

char stack[30];
int top = 0;

bool spec = 0;
void push(char x){
    if (top == 30)
        printf("Full\n");
    else{
        stack[top] = x;
        top  ;
    }
}

void pop(char x){
    if (top == 0)
        spec = 1;
    else{
        if (x == stack[top-1])
            top--;
    }
}

int main()
{
    char temp[30];
    scanf("%s", temp);

    for (int i = 0; temp[i] != '\0'; i  )
    {
        if (temp[i] == '(' || temp[i] == '{' || temp[i] == '[')
            push(temp[i]);
        else if (temp[i] == ')' || temp[i] == '}' || temp[i] == ']')
            pop(temp[i]);
    }

    for (int i = 0; i < top; i  ){
        printf("%c", stack[i]);
    }
    if (top != 0)
        printf("Unbalanced");
    else
        printf("Balanced");
    return 0;
}

CodePudding user response:

When you read the closing parenthesis or braces you should not only pop the stack, but also compare the popped value to see if it's a corresponding opening parenthesis or brace.

So you first need to modify the pop function to return the popped value:

char pop(void)
{
    if (top > 0)
    {
        return stack[--top];
    }
    else
    {
        return 0;  // Error: Stack underflow
    }
}

Then you need to get the popped character and check it:

if (temp[i] == '(' || temp[i] == '{' || temp[i] == '[')
{
    push(temp[i]);
}
else if (temp[i] == ')' || temp[i] == '}' || temp[i] == ']')
{
    char opening = pop();  // Pop and get value

    if ((temp[i] == ')' && opening != '(') ||
        (temp[i] == '}' && opening != '{') ||
        (temp[i] == ']' && opening != '['))
    {
        // TODO: Not matching, handle it in some appropriate way
    }
}

CodePudding user response:

Once one gets going, it's hard to stop with these things. Intending to "lightly touch" your code, this is what resulted. I hope the comments make clear what it is doing... Primarily, for any of the 3 types of "open", this "pushes" its mate onto the stack. Then when a "close" is encountered, it is passed to popExpect() for validation against what's on the top of the stack (if anything). That function returns a boolean yes/no to continue.

Anyway...

#include <stdio.h>

#define STACKSIZE 30 // One "magic number" in this source

char stack[ STACKSIZE ]; // Global, but let's go with it
int top = 0;

void push( char x ) { // little change here
    if( top == STACKSIZE )
        puts( "Stack Full");
    else
        stack[ top   ] = x;
}

bool popExpect( char c ) { // compare expected char on top with passed char
    return top && c == stack[ --top ];
}

// function "broken out" for repeated tests
bool chk( const char *str ) {
    char *cp, pairs[] = "(){}[]"; // three important pairs

    bool isGood = true; // optimism

    // while good and not finished string
    for( int i = 0; isGood && str[ i ]; i   )

        // is this char one of the "special" ones?
        if( ( cp = strchr( pairs, str[ i ] ) ) != NULL ) {

            // which "special" char is it?
            int off = cp - pairs;

            // because "paired" 0,2,4 are open, 1,3,5 are close
            if( off%2 == 0 ) // opening
                push( cp[1] ); // push the close that matches this open
            else // special closing
                isGood = popExpect( str[ i ] ); // does this close match?
        }

    // all good and nothing left on the stack
    return isGood && top == 0;
}

int main() {
    const char *s1 = "(foobar)({}){bar}[[[(foo)]]]"; // balanced
    const char *s2 = "(foobar)({}){ { bar}[[[(foo)]]]"; // unbalanced open
    const char *s3 = "(foobar)({}){ ] bar}[[[(foo)]]]"; // unbalanced close

    puts( chk( s1 ) ? "Balanced" : "Unbalanced" );
    puts( chk( s2 ) ? "Balanced" : "Unbalanced" );
    puts( chk( s3 ) ? "Balanced" : "Unbalanced" );

    return 0;
}
  • Related