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.
Related
char *string = (char *) malloc(sizeof(char) * sz);
code right before this->void insert_word(word *root, char string1[], int linenumber) { int sz=strlen(string1)<=MAX_WORD_LENGTH?strlen(string1):MAX_WORD_LENGTH; Code block 3 has the entire context
Sometimes malloc() returns a populated memory location while using it.
What bothers me is that this is not random.
(This program consists of taking words from a file and passing them to this function. For THE SAME WORD, the function behaviour(in particular that of malloc()) is different.
For the inputs
string1=0x7fffffffdf10 "lol" root=BST, sz gets a value of 3
The value allocated to string by malloc() is 0x55555555c510 "\340\305UUUU" Why is malloc not pointing to an empty memory location? (This is not random behaviour, it is predictable and repeatable)
Furthermore,this loop runs an infinite amount of time for some reason
while(strcmp(string1,string)!=0)
{
free(string);
string=NULL;
string = (char *) malloc(sizeof(char) * sz);
strncpy(string,string1,sz);
}
MORE RELAVANT CODE
#define MAX_WORD_LENGTH 20
Definition of the structures
typedef struct linkedList
{
int number;
struct linkedList *next;
}list;
typedef struct word_with_count
{
char* string;
list *linenumbers;
struct word_with_count *left;
struct word_with_count *right;
}word;```
[3] ) The function
void insert_word(word *root, char string1[], int linenumber) {
int sz=strlen(string1)<=MAX_WORD_LENGTH?strlen(string1):MAX_WORD_LENGTH;
char *string = (char *) malloc(sizeof(char) * sz);
strncpy(string,string1,sz);
if (root==NULL) {
return;
} else if (strcmp(string, root->string) < 0) {
if (root->left == NULL) {
root->left = createword(string, linenumber);
} else {
insert_word(root->left, string, linenumber);
}
} else if (strcmp(string, root->string) > 0) {
if (root->right == NULL) {
root->right = createword(string, linenumber);
} else {
insert_word(root->right, string, linenumber);
}
} else {
append_list(linenumber, root->linenumbers);
}
free(string);
}
main() which calls this function
int main() {
char path[MAX_PATH_LENGTH];
FILE *fp;
fgets(path, MAX_PATH_LENGTH, stdin);
if (strlen(path) > 0 && path[strlen(path) - 1] == '\n')
path[strlen(path) - 1] = '\0';
fp = fopen(path, "r");
if (fp == NULL) {
printf("File not found\n");
return 0;
}
char ch;
int line_count = 1;
char current_word[MAX_WORD_LENGTH] = "";
word *root = NULL;
while (!feof(fp)) {
ch = fgetc(fp);
//printf("%c", ch);
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
if (ch >= 'A' && ch <= 'Z')
ch = ch - 'A' + 'a';
strncat(current_word, &ch, 1);
} else if (ch == '-') {
continue;
} else {
if (strlen(current_word) > 2) {
if (root == NULL) {
root = createword(current_word, line_count);
} else {
insert_word(root, current_word, line_count);
}
}
memset(current_word, 0, sizeof(current_word));
if (ch == '\n') {
line_count++;
}
}
}
if (strlen(current_word) > 2) {
if (root == NULL) {
root = createword(current_word, line_count);
} else {
insert_word(root, current_word, line_count);
}
}
fclose(fp);
// print_tree(root);
//printf("\n");
//print_tree(root);
int status=delete_low_ocurrence(root, NULL, 3);
if (status == -1)root = NULL;
print_tree(root);
freetree(root);
return 0;
}
5)Auxilary function used by this function
word* createword(char string[], int linenumber)
{
word *newword = (word*)malloc(sizeof(word));
int sz=strlen(string)<=MAX_WORD_LENGTH?strlen(string):MAX_WORD_LENGTH;
newword->string = (char*)malloc(sizeof(char)*sz);
strncpy(newword->string, string,sz);
newword->linenumbers = (list*)malloc(sizeof(list));
newword->linenumbers->number = linenumber;
newword->linenumbers->next = NULL;
newword->left = NULL;
newword->right = NULL;
return newword;
}
Textfile given as input
much2f
much3f
lol
lol
lol
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop
Why is malloc not pointing to an empty memory location?
Because it can. The content of the allocated memory via malloc() is not specified.
If code needs zeroed out memory, see calloc().
Bad code
strncpy(string,string1,sz) does not result in string being a string as it may lack null character termination. The following (strcmp(string... is then undefined behavior. Instead, do not use strncpy(), use strcpy() and make certain the prior allocation has enough room for the terminating null character.
strncpy(string,string1,sz);
...
} else if (strcmp(string, root->string) < 0) { // bad
Repaired code
word* createword(const char string[], int linenumber) {
word *newword = calloc(1, sizeof *newword);
size_t length = strlen(string);
if (length > MAX_WORD_LENGTH) {
length = MAX_WORD_LENGTH;
}
char *s = malloc(length + 1); // Include room for the \0
list *linenumbers = calloc(1, sizeof *linenumbers);
// Test allocation success
if (newword == NULL || s == NULL || linenumbers == NULL) {
free(newword);
free(s);
free(linenumbers);
return NULL;
}
memcpy(s, string, length); // Only copy the first 'length' characters.
s[length] = 0;
newword->string = s;
newword->linenumbers = linenumbers;
newword->linenumbers->number = linenumber;
newword->linenumbers->next = NULL;
newword->left = NULL;
newword->right = NULL;
return newword;
}
Why is “while ( !feof (file) )” always wrong?
feof(fp) improperly used here. fgetc() returns 257 different values. Do not use char ch.
//char ch;
//...
//while (!feof(fp)) {
// ch = fgetc(fp);
int ch;
...
while ((ch = fgetc(fp)) != EOF) {;
This is quite normal behaviour. 'malloc' just does the memory allocation, it makes no commitment on what's already in that memory location. What you probably need is 'calloc', which clears the memory and then allocates it to your program.
I've been stuck with the dcl program from chapter 5.12 in K&R C. It is basically a program which accepts a C variable/function/table declaration and prints a description of it in English. It works for simple declarations such as int a but fails with more complicated ones. For example, when I enter int (*pf)() I get the output
error: expected name or (dcl)
Syntax error
: int
error: expected name or (dcl)
: function that returns pf
Below is the portion of the code related to the program. The getch() and ungetch() functions are in a separate file.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "getch.h"
#define MAXTOKEN 100
enum { NAME, PARENS, BRACKETS };
void dcl(void);
void dirdcl(void);
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
int main(void)
{
while (gettoken() != EOF) {
strcpy(datatype, token);
out[0] = '\0';
dcl();
if (tokentype != '\n')
printf("Syntax error\n");
printf("%s: %s %s\n", name, out, datatype);
}
return 0;
}
void dcl(void)
{
int ns;
for (ns = 0; gettoken() == '*'; )
ns++;
dirdcl();
while (ns-- > 0)
strcat(out, " pointer to");
}
void dirdcl(void)
{
int type;
if (tokentype == '(') {
dcl();
if (tokentype != ')')
printf("error: missing )\n");
} else if (tokentype == NAME)
strcpy(name, token);
else
printf("error: expected name or (dcl)\n");
while ((type=gettoken()) == PARENS || type == BRACKETS) {
if (type == PARENS)
strcat(out, " function that returns");
else {
strcat(out, " array");
strcat(out, token);
strcat(out, " of");
}
}
}
int gettoken(void)
{
int c;
char *p = token;
while ((c = getch()) == ' ' || c == '\t')
;
if (c == '(') {
if ((c = getch()) == ')') {
strcpy(token, "()");
return tokentype = PARENS;
} else {
ungetch(c);
return tokentype = ')';
}
} else if (c == '[') {
for (*p++ = c; (*p++ = getch()) != ']'; )
;
*p = '\0';
return tokentype = BRACKETS;
} else if (isalpha(c)) {
for (*p++ = c; isalnum(c = getch()); )
*p++ = c;
*p = '\0';
ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
}
Could you please help me pinpoint the mistake?
On p124 Brian and Dennis say "Since the programs are intended to be illustrative, not bullet-proof, there are significant restricts on dcl."
The final sentence in the paragraph has this version of the author's final cop-out:
"These improvements are left as exercises."
This could be a good time to dust off yacc.
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 $
Ive been asked to write a function that merges two sorted (ascii sorted) strings without duplicates.
For example, for string1 = aabcd, and string2 = abbcdg, the end result string should be abcdg.
For some reason, the end result string doesnt allocate well, or so I think.. its not working anyway and its giving me weird characters instead of what its supposed to give.
The value of stringToReturn is always 0xfffffffe "Error reading characters of string", and inside it says "Unable to read memory"
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "bohan.h"
int main() {
char* string1;
char* string2;
char* mergedString;
string1 = (char*)malloc(MAX_TEXT + 1);
if (string1 == NULL)
return;
string2 = (char*)malloc(MAX_TEXT + 1);
if (string2 == NULL)
return;
printf("Please enter string no. 1: ");
scanf("%s", string1);
printf("Please enter string no. 2: ");
scanf("%s", string2);
mergedString = merge_strings(string1, string2);
printf("%s \n", mergedString);
free(string1);
free(string2);
free(mergedString);
}
bohan.c:
#include <stdio.h>
#include <stdlib.h>
#include "bohan.h"
int checkNumberOfChars(char* text) {
int sum = 0;
if (text == NULL)
return 0;
while (*text != '\0')
{
sum++;
text++;
}
return sum;
}
char* merge_strings(char* text1, char* text2) {
int i;
int hasChanged;
char* stringToReturn;
if (text1 == NULL && text2 == NULL)
return NULL;
stringToReturn = (char *)malloc(checkNumberOfChars(text1) + checkNumberOfChars(text2) + 1);
if (stringToReturn == NULL)
return NULL;
for (i = 1; i <= MAX_ASCII; i++) {
hasChanged = FALSE;
if (*text1 != '\0' || *text2 != '\0') {
if (*text1 != '\0') {
if (i == *text1) {
*stringToReturn = i;
stringToReturn++;
hasChanged = TRUE;
while (*text1 == i)
text1++;
}
}
if (*text2 != '\0') {
if (i == *text2) {
if (!hasChanged) {
*stringToReturn = i;
stringToReturn++;
}
while (*text2 == i)
text2++;
}
}
}
else
break;
}
return stringToReturn;
}
bohan.h:
#ifndef DEF
#define TRUE 1
#define FALSE 0
#define MAX_TEXT 100
#define MAX_ASCII 255
int checkNumberOfChars(char *text);
char *merge_strings(char *text1, char *text2);
#endif DEF
In the merge_strings method you must define a pointer (beginOfStringToReturn) to hold the address of the beginning of the merged string. The merge_strings method should return this pointer at the end. Also add '\0' after the merged string has been built.
char* merge_strings(char* text1, char* text2) {
int i;
int hasChanged;
char* stringToReturn;
if (text1 == NULL && text2 == NULL)
return NULL;
stringToReturn = (char *)malloc(checkNumberOfChars(text1) + checkNumberOfChars(text2) + 1);
char* beginOfStringToReturn = stringToReturn;
if (stringToReturn == NULL)
return NULL;
for (i = 1; i <= MAX_ASCII; i++) {
hasChanged = FALSE;
if (*text1 != '\0' || *text2 != '\0') {
if (*text1 != '\0') {
if (i == *text1) {
*stringToReturn = i;
stringToReturn++;
hasChanged = TRUE;
while (*text1 == i)
text1++;
}
}
if (*text2 != '\0') {
if (i == *text2) {
if (!hasChanged) {
*stringToReturn = i;
stringToReturn++;
}
while (*text2 == i)
text2++;
}
}
}
else
break;
}
*stringToReturn = '\0';
return beginOfStringToReturn;
}
In bohan.h include the guard like this:
#ifndef BOHAN_H
#define BOHAN_H
#define TRUE 1
#define FALSE 0
#define MAX_TEXT 100
#define MAX_ASCII 255
int checkNumberOfChars(char *text);
char *merge_strings(char *text1, char *text2);
#endif
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.