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;
}