Below is the code to determine balancing of symbol.
If the expression is balanced then it should print appropriate message. E.g:
((A+B))+(C+D)) --> Balanced
((A+B)+(C+D) ---> Unbalanced
((A+B)+(C+D}) --> Unbalanced
Here is the code
#include <stdio.h>
#include <stdlib.h>
struct Stack {
char data;
struct Stack *next;
};
void push(struct Stack **top, char data) {
struct Stack *new_node;
if (*top == NULL) {
new_node = malloc(sizeof(struct Stack));
new_node->data = data;
new_node->next = *top;
*top = new_node;
} else {
new_node = malloc(sizeof(struct Stack));
new_node->data = data;
new_node->next = *top;
*top = new_node;
}
}
char pop(struct Stack **top, int flag) {
if (*top != NULL && flag == 0) {
printf("\n Expression is In-Valid :) \n");
return '\0';
}
if (*top == NULL && flag == 1) {
printf("\n Unbalanced Expression \n");
return '\0';
}
if (*top != NULL && flag == 1) {
struct Stack *temp = *top;
char op;
op = (*top)->data;
*top = (*top)->next;
free(temp);
return op;
}
}
/*
void display(struct Stack *top) {
struct Stack *temp = top;
while (temp) {
printf("\n %c", temp->data);
temp = temp->next;
}
}
*/
int main(void) {
struct Stack *top = NULL;
int i = 0;
char str[] = "((A+B)+[C+D])", op;
printf("\n Running the programe to check if the string is balanced or not ");
for (i = 0; str[i] != '\0'; ++i) {
if (str[i] == '(' || str[i] == '[' || str[i] == '{' || str[i] == '<')
push(&top, str[i]);
else
if (str[i] == ')' || str[i] == ']' || str[i] == '}' || str[i] == '>') {
op = pop(&top, 1);
if ((op == '(' && str[i] == ')') ||
(op == '[' && str[i] == ']') ||
(op == '{' && str[i] == '}') ||
(op == '<' && str[i] == '>')) {
continue;
} else {
printf("\n The expression is un-balanced \n");
break;
}
}
}
pop(&top, 0);
return 0;
}
But it does not give the desired output. I have debugged the code but was not able to find the issue.
How can I have it print the appropriate message ?
You should immediately clean the stack and stop processing as soon as you detect something unbalanced, and print "Balanced" when you reach return 0. And you should print "Unbalanced" from one single place in your code.
And it is bad that one branch of pop does not return a value when it is declared to return one.
So, pop could become:
char pop(struct Stack **top,int flag)
{
if(*top!=NULL && flag==0)
{
return '\0';
}
if(*top==NULL && flag ==1)
{
return '\0';
}
if(*top!=NULL && flag==1)
{
struct Stack *temp=*top;
char op;
op=(*top)->data;
*top=(*top)->next;
free(temp);
return op;
}
// *top == null && flag == 0
return 'O'; // for OK
}
I would add a clean method - not required because program exit cleans the stack, but I do prefer that:
void clean(struct Stack *top) {
struct Stack *next;
while (top != NULL) {
next = top->next;
free(top);
top = next;
}
}
And some changes in main:
int main(void)
{
struct Stack *top=NULL;
int i=0, err=0;
...
else
{
err = 1;
break;
}
}
}
if (err || (pop(&top,0) == '\0')) {
printf("\n The expression is un-balanced \n");
clean(top);
// return 1; optionally if you want to return a different value to environment
}
else {
printf("\n The expression is balanced \n");
}
return 0;
}
Your pop function is wrong.
You have not handled if top is null and flag is 0. It might also be a case.
Secondly, why do you **top in your push\pop signature when you should be passing top in it. I think it should have *top in its signature.
Also, why you use if in push. Its not needed. You are essentially doing same thing.
You can do this simply by simple modification in this code. I take it from Find maximum depth of nested parenthesis in a string this. It's also help for knowing details. I think it's helpful to you
#include <iostream>
using namespace std;
// function takes a string and returns the
// maximum depth nested parenthesis
int maxDepth(string S)
{
int current_max = 0; // current count
int max = 0; // overall maximum count
int n = S.length();
// Traverse the input string
for (int i = 0; i< n; i++)
{
if (S[i] == '(')
{
current_max++;
// update max if required
if (current_max> max)
max = current_max;
}
else if (S[i] == ')')
{
if (current_max>0)
current_max--;
else
return -1;
}
}
// finally check for unbalanced string
if (current_max != 0)
return -1;
return max;
}
// Driver program
int main()
{
string s = "( ((X)) (((Y))) )";
if (maxDepth(s) == -1)
cout << "Unbalance";
else
cout << "Balance";
return 0;
}
Time Complexity : O(n)
Auxiliary Space : O(1)
Thanks for the suggestions. Here is my below working code of the same problem
#include<stdio.h>
#include<stdlib.h>
struct Stack{
char data;
struct Stack *next;
};
void push(struct Stack **top,char data)
{
struct Stack *new_node;
new_node=malloc(sizeof(struct Stack));
new_node->data=data;
new_node->next=*top;
*top=new_node;
}
int compare(char str,char op)
{
if( (op == '(' && str == ')') || (op == '{' && str == '}') || (op == '[' && str == ']') || (op == '<' && str == '>') )
return 1;
else
return 0;
}
int pop(struct Stack **top,char str)
{
char op,ret;
struct Stack *temp=*top;
if(*top==NULL)
return 0;
else if(*top!=NULL)
{
// Pop the element and then call comapre function
op=(*top)->data;
free(temp);
*top=(*top)->next;
return(ret=compare(str,op));
}
}
void display(struct Stack *top)
{
struct Stack *temp=top;
while(temp!=NULL)
{
printf("%c ",temp->data);
temp=temp->next;
}
printf("\n");
}
int isNotEmpty(struct Stack *top)
{
if(top!=NULL)
return 1;
else
return 0;
}
int main(void)
{
struct Stack *top=NULL;
int i=0,y,flag=0;
char str[]="((A+B)+(C+D)>",op;
printf("\n Running the programe to check if the string is balanced or not ");
for(i=0;str[i]!='\0';++i)
{
if( str[i] == '(' || str[i] == '[' || str[i] == '{' || str[i] == '<' )
push(&top,str[i]);
else if( str[i] == ')' || str[i] == ']' || str[i] == '}' || str[i] == '>')
{
y=pop(&top,str[i]);
if(!y)
{
printf("\n Unbalanced Expression ");
flag=1;
}
}
}
if(!flag)
{
if(isNotEmpty(top))
printf(" \nUnbalanced Expression ");
else
printf(" \n Balanced Expression ");
}
printf("\n");
return 0;
}
Check this code it is super easy and easy to understand
package com.codewithsouma.stack;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
public class Expression {
private final List<Character> leftBrackets = Arrays.asList('(','{','[','<');
private final List<Character> rightBrackets = Arrays.asList(')','}',']','>');
public boolean isBalanced(String input) {
Stack<Character> stack = new Stack<>();
for (char ch : input.toCharArray()) {
if (isLeftBracket(ch))
stack.push(ch);
if (isRightBracket(ch)) {
if (stack.isEmpty()) return false;
char top = stack.pop();
if (!bracketsMatch(top,ch)) return false;
}
}
return stack.isEmpty();
}
private boolean isRightBracket(char ch) {
return rightBrackets.contains(ch);
}
private boolean isLeftBracket(char ch) {
return leftBrackets.contains(ch);
}
public boolean bracketsMatch(char left, char right){
return leftBrackets.indexOf(left) == rightBrackets.indexOf(right);
}
}
At first, we create a hash table and store all brackets, left brackets are key and the value is its corresponding right brackets. Then we take an expression string from the user and create a character array. then we iterate the array and take a character then we check is this character left brackets or not if it is left bracket then we put into the stack (leftBracketContainer) otherwise we check is it the right bracket if right bracket then we pop the left bracket from the stack and find the closing bracket/ opposite bracket from the hash table and matching the current character/bracket if not matched ( for example our stack contain { this bracket so its closing bracket is } we find from the hash map and our current character = ] current character != opposite bracket ) return false otherwise we continue. At last when loop over then stack should empty. (if stack contain one more left bracket that means our expression needs another right bracket) if stack empty that means our expression is balanced otherwise not.
N:B when we check left bracket or not using isItLeftBracket(ch) then we check is our map contains the keys because all keys are left brackets like the ways we cheak right bracket by using isItRightBracket(ch) here we chake our map contains the value because all the value of the map are right bracket
package com.codewithsouma.stack;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class BalancedExpressionUsingMap {
private final Map<Character,Character> map;
public BalancedExpressionUsingMap() {
this.map = new HashMap<>();
map.put('(',')');
map.put('[',']');
map.put('<','>');
map.put('{','}');
}
public boolean isBalanced(String expression){
Stack<Character> leftBracketContainer = new Stack<>();
char [] arrayOfCharacter = expression.toCharArray();
for (char ch : arrayOfCharacter) {
if(isItLeftBracket(ch))
leftBracketContainer.push(ch);
else if(isItRightBracket(ch)){
if(leftBracketContainer.isEmpty()) return false;
char leftBracket = leftBracketContainer.pop();
char oppositeBracket = getOppositeBracket(leftBracket);
if (oppositeBracket != ch) return false;
}
}
return leftBracketContainer.isEmpty();
}
private char getOppositeBracket(char leftBracket) {
return map.get(leftBracket);
}
private boolean isItRightBracket(char ch) {
return map.containsValue(ch);
}
private boolean isItLeftBracket(char ch) {
return map.containsKey(ch);
}
}
Instead of allocating a stack for the delimiters, you can use a recursive function that skips balanced subexpressions and returns NULL upon mismatches:
#include <stdio.h>
const char *check(const char *s, char open) {
while (*s) {
switch (*s++) {
case ')': return (open == '(') ? s : NULL;
case ']': return (open == '[') ? s : NULL;
case '}': return (open == '{') ? s : NULL;
case '>': return (open == '<') ? s : NULL;
case '(':
case '[':
case '{':
case '<':
s = check(s, s[-1]);
if (s == NULL)
return NULL;
break;
}
}
if (open) {
/* closing delimiter not found */
return NULL;
}
return s;
}
void test(const char *s) {
printf("%s -> %s\n", s, check(s, 0) ? "Balanced" : "Unbalanced");
}
int main() {
test("((A+B)+(C+D))");
test("((A+B))+(C+D))");
test("((A+B)+(C+D)");
test("((A+B)+(C+D})");
return 0;
}
Output:
((A+B)+(C+D)) -> Balanced
((A+B))+(C+D)) -> Unbalanced
((A+B)+(C+D) -> Unbalanced
((A+B)+(C+D}) -> Unbalanced
Note that contrary to your assertion, ((A+B))+(C+D)) is unbalanced.
Related
The giver code is for converting infix to postfix using stack. I tried it everywhere no errors or warning were shown except for one time there was a segmentation fault on my school's computer. If anyone can explain the correct way to write the code it'll be very helpful as I'm unable to find.
In code we scan the infix expression and check if it's an operator and then if it is an operator we push it to stack and character or digit go to an array. We then pop the operator from the stack if we find another operator of more precedence than the previous pushed operator and we keep popping till we get less precedence operator in stack and append it to the array that is also our output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<ctype.h>
struct stack
{
int size;
int top;
char *arr;
};
int stacktop(struct stack *sp)
{
return sp->arr[sp->top];
}
void push(struct stack *ptr, char val)
{
if (ptr->top == ptr->size - 1)
{
printf("Stack is full\n");
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack *ptr)
{
int a;
if (ptr->top == -1)
{
printf("\n");
}
else
{
a = ptr->arr[ptr->top];
ptr->top--;
return a;
}
}
int isoperator(char symbol)
{
if (symbol == '^' || symbol == '*' || symbol == '/' || symbol == '+' || symbol == '-')
{
return 1;
}
else
{
return 0;
}
}
int precedence(char symbol)
{
if (symbol == '^')
{
return (3);
}
else if (symbol == '*' || symbol == '/')
{
return (2);
}
else if (symbol == '-' || symbol == '+')
{
return (1);
}
else
{
return (0);
}
}
char *infix_to_postfix(char *infix)
{
struct stack *sp = (struct stack *)malloc(sizeof(struct stack));
sp->size = 50;
sp->top = -1;
sp->arr = (char *)malloc(sp->size * sizeof(char));
char *postfix = (char *)malloc(strlen((infix) + 1) * sizeof(char));
int i = 0, j = 0, x = 0;
while (infix[i] != '\0')
{
if (infix[i] == '(')
{
push(sp, infix[i]);
}
else if( isdigit(infix[i]) || isalpha(infix[i])){
postfix[j]=infix[i];
j++;
}
else if (isoperator(infix[i])==1)
{
x=pop(sp);
while(isoperator(x)==1 && precedence(x)>=precedence(infix[i])){
postfix[j]=x;
j++;
x=pop(sp);
}
push(sp, x);
push(sp, infix[i]);
}
else if (infix[i] == ')')
{
x = pop(sp);
while (x != '(')
{
postfix[j] = x;
j++;
x = pop(sp);
}
}
i++;
}
while (!(sp->top == -1))
{
postfix[j] = pop(sp);
j++;
}
postfix[j] = '\0';
return postfix;
}
int main()
{
char *infix;
printf("Enter your expression\n");
scanf("%s",infix);
printf("Postfix is %s", infix_to_postfix(infix));
return 0;
}
The pointer variable char *infix doesn't point to anything so it's not about VSCode and other compilers. It's complete luck that it's working on VSCode.
You should allocate some memory either statically char infix[100] or dynamically char *infix = (char *)malloc(100).
Also, you have a problem with pop function. You shouöd always return a char from this function not only under certain conditions.
I am working on a simple parser which takes a string as input and parses a string to see if the opening and closing parentheses/brackets/braces are correctly placed. One step in this involves me skipping every character that is not a valid token (a parenthesis, bracket, or brace), because at this point I don't care whether the expression inside the parentheses are valid or not–I'm only interested in whether the parentheses are syntactically correct. I wrote an if statement which tells the loop to skip to the next iteration when it encounters anything that's not an opening or closing brace, but the code looks ugly and is repetitive. I was wondering if there was a better way to do it–perhaps with an enum. Directly below is the function in question, (parse), and below that, I've pasted the code for the entire program so far. If you answer or attempt to answer this, thank you for your time.
void parse(char *string) {
for (int i = 0; i < strlen(string); i++) {
if (string[0] == ')' || string[0] == ']' || string[0] == '}') {
printf("ParseError: Statement begins with invalid token '%c'", string[0]);
return;
}
if (string[i] != '(' || string[i] != '[' || string[i] != '{' ||
string[i] != ')' || string[i] != ']' || string[i] != '}') {
continue;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
char character;
struct Node *link;
} * top;
struct Node *getNewNode(char);
void push(char);
void pop(void);
void parse(char *);
void print(void);
int main() {
top = NULL;
char string[100];
char *string_ptr = string;
printf("Enter an expression to parse: ");
fgets(string, sizeof(string), stdin);
parse(string_ptr);
print();
}
struct Node *getNewNode(char character) {
struct Node *newNode = (struct Node *)(malloc(sizeof(struct Node)));
newNode->character = character;
newNode->link = top;
return newNode;
}
void push(char character) {
struct Node *newNode = getNewNode(character);
top = newNode;
}
void pop(void) {
struct Node *temp;
if (top == NULL) {
printf("Stack is empty!");
return;
}
temp = top;
top = top->link;
free(temp);
temp = NULL;
}
void print(void) {
struct Node *temp = top;
while (temp != NULL) {
printf("%c", temp->character);
temp = temp->link;
}
}
void parse(char *string) {
for (int i = 0; i < strlen(string); i++) {
if (string[0] == ')' || string[0] == ']' || string[0] == '}') {
printf("ParseError: Statement begins with invalid token '%c'", string[0]);
return;
}
if (string[i] != '(' || string[i] != '[' || string[i] != '{' ||
string[i] != ')' || string[i] != ']' || string[i] != '}' ||) {
continue;
}
}
}
There are college courses on parsing theory. We construct software “machines” of various kinds to parse strings, so good solutions for issues like this involve incorporating them into an overall parsing scheme, not solving each one individually.
However, given that, a typical way to handle something like this is to prepare an array with information about the characters:
#include <limits.h>
// Define bit flags for character properties.
enum { IsOpener = 1, IsCloser = 2, };
// Initialize array with flags for characters.
static unsigned CharacterProperties[UCHAR_MAX+1] =
{
['('] = IsOpener,
['['] = IsOpener,
['{'] = IsOpener,
[')'] = IsCloser,
[']'] = IsCloser,
['}'] = IsCloser,
};
…
if (CharacterProperties[string[0]] & IsOpener)
… // Here string[0] is one of the “open parentheses” type of characters.
Note there are some sign issues to watch out for: The subscript to CharacterProperties should be nonnegative, so string should be unsigned char * or you should cast it with (unsigned char) in the subscript or you should ensure char is unsigned. And, if any of the characters in the initialization could be negative (are not in C’s basic execution character set), they should be cast too.
This may be a good use case for a switch:
void parse( char *string )
{
/**
* Make sure string[0] is valid first
*/
switch( string[0] )
{
case ')':
case ']':
case '}':
fprintf( stderr, "parse error..." );
return;
break;
default:
break;
}
/**
* Compute the length of the string once rather
* than every time through the loop.
*/
size_t len = strlen( string );
for ( size_t i = 0; i < len; i ++ )
{
/**
* Is the current character a delimiter?
*/
switch( string[i] )
{
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
// we'll process the delimiter character following
// the end of the switch statement
break;
default:
// this is not a delimiter, go back to the beginning of
// the loop
continue;
break;
}
// process delimiter character
}
}
but that heavily depends on how you're going to process other characters once you beef up your parser. Switches can get ugly and unmaintainable in a hurry. I've written this such that the switches act only as filters; they simply decide whether to proceed with the current operation or not, there's no processing logic in either one.
I'm making a data structure that stores strings from a file in memory. The struture is:
typedef struct node
{
bool end;
struct node *letters[27];
} node;
Each char from the string goes through a hash function:
int
hash(int letter)
{
int n;
// converts upper case to a number from 1 to 26
if (letter >= 65 && letter <= 90)
n = letter - 64;
// converts letter case to a number from 1 to 26
else if (letter >= 97 && letter <= 122)
n = letter - 96;
// converts apostrophe to 27
else if (letter == '\'')
n = 0;
return n;
}
Thus, the structure is similar to a tree where the position of each pointer in the array corresponds to a letter, as follows:
tree
The function that loads the words into memory is as follows:
bool
load(const char *dict)
{
// open the dictionary file
FILE *infile = fopen(dict, "r");
if (infile == NULL)
{
return false;
}
// pointer for the first tree
node *first = calloc(28, sizeof(node));
if (first == NULL)
return false;
//pointer to the nodes
node *nextptr = NULL;
// word storage variables
int index = 0;
char word[LENGTH+1];
// stores the words of the file in the struct
for (int c = fgetc(infile); c != EOF; c = fgetc(infile))
{
// reads only letters and apostrophes
if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122) || (c == '\''))
{
word[index] = c;
// creates a new tree from the first tree
if (index == 0)
{
// checks if there is a struct for the char
if (first->letters[hash(word[0])] != NULL)
{
nextptr = first->letters[hash(word[0])];
index++;
}
// creates a new struct for the char
else
{
first->letters[hash(word[0])] = calloc(28, sizeof(node));
if (first->letters[hash(word[0])] == NULL)
return false;
nextptr = first->letters[hash(word[0])];
index++;
}
}
// create the following structures
else
{
// checks if there is a struct for the char
if (nextptr->letters[hash(word[index])] != NULL)
{
nextptr = nextptr->letters[hash(word[index])];
index++;
}
// creates a new struct for the char
else
{
nextptr->letters[hash(word[index])] = calloc(28, sizeof(node));
if (nextptr->letters[hash(word[index])] == NULL)
return false;
nextptr = nextptr->letters[hash(word[index])];
index++;
}
}
}
// creates the last struct for a word
else if (c == '\n')
{
// ends the word
word[index] = '\0';
// the boolean end is set to true, defining the end of the word
nextptr->end = true;
nextptr = NULL;
// prepares for a new word
index = 0;
}
}
return true;
}
The function that has an error is an function that check strings and verify if is in the structure:
bool
check(const char *word)
{
node *checkptr = first;
for (int i = 0; i < sizeof(word); i++)
{
if (word[i] == '\0' && checkptr->end == true)
return true;
else if (checkptr->letters[hash(word[i])] != NULL)
checkptr = checkptr->letters[hash(word[i])];
else
return false;
}
return false;
}
When the program is started, segmentation fault occurs on the line else if (checkptr->letters[hash(word[i])] != NULL) and valgrind shows Invalid read of size 8.
I will still create a function to give the necessary free but I guess that the problem is there, mainly because I tried to check if the checkptr pointer was really set to the same structure as the first, but I discover that first is set to NULL, why?
Sorry for my bad english, i'm a beginner programmer and it's my first time on Stack Overflow, but I really don't know how to solve this. If someone can help me in any way, i thank you in advance.
The problem was solved. The error really was in the pointer first. I had accidentally used calloc for a new pointer, instead of the original first, so check was accessing the original first pointer (which had remained NULL).
I'm trying to make a parentheses checker with implementing stack. The program will print valid if the input have a correct parentheses pattern
input: {[()]}
output: valid
input: {()[()]}
output: valid
input: (()))
output: unvalid
continuously
But what happen after i input the data is :
()
the program prints this unlimited loop
valid
valid
valid
valid
valid
. . . and so on
same with
(()))
It works normally if put break; on here, but it won't be continuous and would instantly ends the program, and wont ask for the input again.
if(isempty(stack)){
printf("Valid parenthesis expression\n");
break;
} else{
printf("Invalid parenthesis expression\n");
break;
}
I can't seem to find the reason why this happened,
can anyone help me or give me some advice about what's going on? So that I can loop to ask for input and print the valid/invalid just only one time?
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct data{
char parent;
struct data *next;
}DATA;
void push(DATA **stack, char parentheses);
int isempty(DATA *stack);
void pop(DATA **stack);
int top(DATA *stack);
int main(int argc, char const *argv[]){
DATA *stack;
char parentheses[100];
int i, flag = 1;
do{
//PUSH
stack = NULL;
printf("Enter parentheses: ");
scanf("%[^\n]", &parentheses);
if(strcmp(parentheses, "-1") == 0){
break;
}
for(i = 0; i < strlen(parentheses); i++){
if(parentheses[i] == '{' || parentheses[i] == '[' || parentheses[i] == '('){
push(&stack, parentheses[i]);
} else if (stack == NULL){
printf("Invalid parenthesis expression\n");
break;
} else if(parentheses[i] == '}' && top(stack) == '{'){
pop(&stack);
} else if (parentheses[i] == ']' && top(stack) == '['){
pop(&stack);
} else if (parentheses[i] == ')' && top(stack) == '('){
pop(&stack);
} else if(parentheses[i] != '{' || parentheses[i] != '[' || parentheses[i] != '(' || parentheses[i] != '}' || parentheses[i] != ']' || parentheses[i] != ']') {
printf("Invalid parenthesis expression\n");
break;
}
}
//POP
if(isempty(stack)){
printf("Valid parenthesis expression\n");
} else{
printf("Invalid parenthesis expression\n");
}
}while(1);
return 0;
}
void push(DATA **stack, char parentheses){
DATA *node = (DATA*) malloc(sizeof(DATA));
node -> parent = parentheses;
node -> next = NULL;
if(!isempty(*stack)) node->next = *stack;
*stack = node;
}
int isempty(DATA *stack){
if(stack == NULL) return 1;
else return 0;
}
void pop(DATA **stack){
DATA *temp = *stack;
*stack = (*stack)->next;
free(temp);
}
int top(DATA *stack){
return stack -> parent; //STACK !ISEMPTY
}
scanf("%[^\n]", &parentheses);
must be
scanf(" %[^\n]", parentheses);
notice the space before the '%' to bypass the newline coming from a previous input, without it on the second turn scanf does nothing. To detect that case and also any invalid input I encourage you to always check the value scanf returns.
In case the input has at least 100 characters you write out of parentheses, do
if (scanf(" %99[^\n]", parentheses) != 1) {
/* EOF */
return -1;
}
parentheses is an array, if you want to use "&" it is specifying the index 0 so &parentheses[0]
Note flag is unused
When you detect an invalid case you can indicate "Valid parenthesis expression" :
pi#raspberrypi:/tmp $ ./a.out
Enter parentheses: (
Invalid parenthesis expression
Enter parentheses: )
Invalid parenthesis expression
Valid parenthesis expression
When the stack is not empty after the for you do not free the still present allocated elements, you have memory leaks.
Because you just save characters in the stack it is much more simple and cheaper in memory to just use an array of char. Because the input is limited to 99 (without the final null character) the stack needs to save 99 characters too, and in fact parentheses can be used for the stack
A proposal still using your stack, fixing problems and also reducing the number tests and simplifying stack functions :
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct data{
char parent;
struct data *next;
} DATA;
void push(DATA **stack, char parentheses);
int isempty(DATA *stack);
void pop(DATA **stack);
int top(DATA *stack);
int main(int argc, char const *argv[]){
DATA *stack = NULL;
char parentheses[100];
char * p;
while (fputs("Enter parentheses: ", stdout),
(scanf(" %99[^\n]", parentheses) == 1) && strcmp(parentheses, "-1")) {
for (p = parentheses; *p; ++p) {
if ((*p == '{') || (*p == '[') || (*p == '('))
push(&stack, *p);
else {
char o;
if (*p == '}')
o = '{';
else if (*p == ')')
o = '(';
else if (*p == ']')
o = '[';
else
o = 0;
if (isempty(stack) || (top(stack) != o))
break;
pop(&stack);
}
}
if (!isempty(stack) || *p) {
puts("Invalid parenthesis expression");
while (! isempty(stack))
pop(&stack);
}
else if (!*p)
puts("Valid parenthesis expression");
}
return 0;
}
void push(DATA **stack, char parentheses) {
DATA *node = malloc(sizeof(DATA));
node->parent = parentheses;
node->next = *stack;
*stack = node;
}
int isempty(DATA *stack) {
return (stack == NULL);
}
void pop(DATA **stack) {
DATA *temp = *stack;
*stack = (*stack)->next;
free(temp);
}
int top(DATA *stack) {
return stack->parent;
}
Compilation and execution:
pi#raspberrypi:/tmp $ gcc -g -Wall s.c
pi#raspberrypi:/tmp $ ./a.out
Enter parentheses: ({[]}())
Valid parenthesis expression
Enter parentheses: (
Invalid parenthesis expression
Enter parentheses: )
Invalid parenthesis expression
Enter parentheses: (]
Invalid parenthesis expression
Enter parentheses: -1
pi#raspberrypi:/tmp $
I'm trying to get brackets to match. What needs to be matched is the '()', '[]', '{}' and '[{}]' is supposed to output true. I don't want it to work for the cases such as '[{]}' or '[{}'. Though, right now my code is not outputting yes for the correct match even when it should be true.
Code (updated):
int booleanBalanceBracket(aStack *theStack){
aStack *balanceStack = NULL;
while(theStack){
if(theStack->token == '[' || theStack->token == '{' || theStack->token == '(')
balanceStack = pushBracket(theStack->token, balanceStack);
else if(theStack->token == ']' || theStack->token == '}' || theStack->token == ')'){
if(balanceStack == NULL)
return 0;
else
balanceStack = popBracket(balanceStack);
}
theStack = theStack->nextItem;
}
if(balanceStack == NULL){
return 1;
}else{
return 0;
}
}
int isMatching(int token1, int token2){
if(token2 == '(' && token1 == ')')
return 1;
else if(token2 == '{' && token1 == '}')
return 1;
else if(token2 == '[' && token1 == ']')
return 1;
else
return 0;
}
Try this simple algorithm:
for each char c in the input
if opener
push on stack
else if closer
if stack is empty or doesn't match
return false
else
remove top of stack
return true if stack is empty, else false
This can be slightly optimized to avoid the empty stack checks and also to avoid an explicit check for EOF by pushing EOF onto the stack initially, and matching EOF to EOF.
your code problem is this line
balanceStack = popBracket(balanceStack);
Does not receive a value obtained by pop. It is also necessary to compare the value popped.
The Example of a simple string
bool booleanBaranceBracket(const char *s){
static const char *left = "{([";
static const char *right = "})]";
size_t len = strlen(s);
char *p, stack[len];
int sp = -1;
int i;
for(i=0;i<len;++i){
if(p = strchr(left, s[i]))
stack[++sp] = s[i];
else if(p = strchr(right, s[i])){
char ch;
if(sp == -1) return false;
ch = stack[sp--];
if(ch != left[p - right]) return false;
}
}
return sp == -1;
}