This is my attempt to write a program that can convert any expression in infix to postfix format. I assign -1 to the top to indicate the stack is empty. When push, the top is incremented, when pop, the top is decremented. However, when I type in a+b, the output only gives me ab without the + operator, while when I type (a+b), it says segmentation fault. I reckon there's something wrong with my stack, but couldn't figure out what went wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SIZE 30
typedef struct Stack
{
int top;
int capacity;
char* storage;
} stack;
int isEmpty(stack* a);
char topelement(stack* a);
char pop(stack* a);
void push(stack* a,char b);
bool isOperand(char a);
int Precedence(char a);
stack* NewStack(char* a);
void InfixPostfix(char* a);
int main(void)
{
char expression[SIZE];
printf("Please enter an expression:");
scanf("%s",expression);
InfixPostfix(expression);
printf("\n");
}
int isEmpty(stack* a)
{
if(a->top==-1)
{
return 1;
}
else
return 0;
}
char topelement(stack* a)
{
return a->storage[a->top];
}
char pop(stack* a)
{
if(isEmpty(a)==1)
{
printf("Stack is Empty\n");
return '$';
}
else
return a->storage[a->top];
--(a->top);
}
void push(stack* a,char b)
{
++(a->top);
a->storage[a->top]=b;
}
bool isOperand(char a)
{
if ( (a >= 'a' && a<= 'z') ||(a>='A' && a<='Z'))
{
return 1;
}
else
return 0;
}
int Precedence(char a)
{
if(a=='+' || a=='-')
{
return 1;
}
if(a=='*' || a=='/')
{
return 2;
}
if(a=='^')
{
return 3;
}
else
return -1;
}
stack* NewStack(char* a)
{
stack* b= malloc(sizeof(stack));
if(b!=NULL)
{
b->top=-1;
b->storage=malloc((strlen(a))*sizeof(char));
return b;
}
else
return NULL;
}
void InfixPostfix(char* a)
{
int i; int j=-1;
stack* b=NewStack(a);
if(b!=NULL)
{
for(i=0; i<strlen(a) ;i++)
{
if(isOperand(a[i]))
{
a[++j]=a[i];
}
if(a[i]=='(')
{
push(b, a[i]);
}
if(a[i]==')')
{
while(isEmpty(b)==0 && topelement(b)!= '(')
{
a[++j]= pop(b);
}
}
else
{
while(isEmpty(b)==0 && Precedence(a[i]) <= Precedence(topelement(b)))
{
a[++j]=pop(b);
push(b,a[i]);
}
}
}
while(isEmpty(b)==0)
{
a[++j]=pop(b);
}
a[++j]='\0';
printf("%s",a);
}
}
Besides the already suggested malloc correction, there are a few more to make.
In pop() there's
return a->storage[a->top];
--(a->top);
where the last code line isn't reached; change that to return a->storage[a->top--];
In InfixPostfix(), else are missing before if(a[i]=='(') and if(a[i]==')').
In InfixPostfix(), after the loop
while(isEmpty(b)==0 && topelement(b)!= '(')
{
a[++j]= pop(b);
}
a pop(b); is missing - the element '(' must as well be removed from the stack.
In InfixPostfix(), the push(b,a[i]); must be removed from the loop
while(isEmpty(b)==0 && Precedence(a[i]) <= Precedence(topelement(b)))
{
a[++j]=pop(b);
push(b,a[i]);
}
and placed after that loop - the operator in a[i] has to be put onto the stack only once.
Related
I saw a problem on the web,i.e, I am trying to sort a stack using another reference stack in C. I tried to do it by implementing it as an array but it is not working.
(condition is that you have to use only arrays)
#include <stdio.h>
int MAXSIZE = 5;
int stack[5];
int tmpstack[5];
int tmp;
int top = -1;
int top2=-1;
int isempty(int A[],int B) {
if(B == -1)
return 1;
else
return 0;
}
int isfull(int A[],int B) {
if(B == MAXSIZE)
return 1;
else
return 0;
}
int pop(int A[],int B) {
int data;
if(!isempty(A,B)) {
data = A[B];
B = B - 1;
return data;
}
else {
printf("Could not retrieve data, Stack is empty.\n");
}
}
int push(int data,int A[],int B) {
if(!isfull(A,B)) {
B = B + 1;
A[B] = data;
}
else {
printf("Could not insert data, Stack is full.\n");
}
}
int sortStack(int stack[])
{
int tmpStack[MAXSIZE];
while (!isempty(stack,top))
{
int tmp = stack[top];
pop(stack,top);
while (!isempty(tmpstack,top2) && tmpstack[top2] > tmp)
{
push(pop(tmpstack,top2),stack,top);
}
push(tmp,tmpstack,top2);
}
return 0;
}
int main() {
int n ,a;
n=5;
for(int i = 0;i < n ; ++i){
scanf("%d",&a);
push(a,stack,top);
}
sortStack(stack);
while (!isempty(tmpstack,top2))
{
printf("%d ",tmpstack[top2]);
pop(tmpstack,top2);
}
return 0;
}
What I did here is that I made similar functions in arrays which we used in stacks only and we are supposed to use them only for implementing our stacks.
I was practising some data structures problems that I did previously but this time I don't know what is going wrong in my code. I looked over a long time but I did not found the mistake. When I'm printing I'm just getting the first character and it looks like e is not being updated. But I've written e++.
#include<stdio.h>
#include "ctype.h"
int stack[20];
int top = -1;
void push(int x)
{
stack[++top] = x;
}
int pop()
{
return stack[top--];
}
int priorityof(char x)
{
if(x=='(')
return 3;
else if(x=='+'|| x=='-')
return 1;
else if(x=='*'|| x=='/')
return 2;
}
int main()
{
char exp[20];
char *e;
e=exp;char x;
scanf("%c",exp);
while(*e!='\0')
{
if(isalnum(*e))
{
printf("%c", *e);
}
else if(*e=='(')
{
push(*e);
}
else if(*e==')')
{
while((x=pop())!='(')
printf("%c",x);
}
else {
while (priorityof(stack[top]) >= priorityof(*e)) {
printf("%c", pop());
push(*e);
}
}
e++;
}
while(top!=-1)
{
printf("%c",pop());
}
}
%c is for single character and reading your question it seems like you are giving more than one character so its a string, use %s.
#include<stdio.h>
#include "ctype.h"
int stack[20]; int top = -1;
void push(int x) {
stack[++top] = x;
}
int pop() { return stack[top--]; }
int priorityof(char x) {
if(x=='(') return 3;
else if(x=='+'|| x=='-') return 1;
else if(x=='*'|| x=='/') return 2;
}
int main() {
char exp[20];
char *e;
e=exp;char x;
scanf("%s",exp);
while(*e!='\0') { if(isalnum(*e)) { printf("%c", *e); } else if(*e=='(') { push(*e); } else if(*e==')') { while((x=pop())!='(') printf("%c",x); } else { while (priorityof(stack[top]) >= priorityof(*e)) { printf("%c", pop()); push(*e); } } e++; } while(top!=-1) { printf("%c",pop()); } }
The code:
#include<stdio.h>
#include<ctype.h>
#define MAX 100
typedef struct stack
{
char data[MAX];
int top;
}stack;
void push(stack *s, char c)
{
s->top++;
if(s->top>MAX)
{
printf("Stack Overflow\n");
return;
}
s->data[s->top]=c;
}
int isEmpty(stack *s)
{
if(s->top==-1)
return 0;
else
return 1;
}
int priority(char c)
{
if(c=='(' || c==')')
return 0;
else if(c=='+' || c=='-')
return 1;
else if(c=='*' || c=='/')
return 2;
else if(c=='^')
return 3;
}
void pop(stack *s)
{
printf("%c ", s->data[s->top]);
s->top--;
}
void infixToPostfix(stack *s)
{
int c;
printf("Enter an expression\n");
while((c=getchar()) != '\n')
{
if(isalnum(c))
printf("%c ", c);
else
{
if(c=='(')
push(s, c);
else if(c==')')
{
while(c != '(')
pop(s);
pop(s);
}
else
{
while((priority(c) <= priority(s->data[s->top])) && isEmpty(s))
{
pop(s);
}
push(s, c);
}
}
}
while(s->top)
{
pop(s);
}
pop(s);
}
int main(void)
{
stack s;
s.top=-1;
infixToPostfix(&s);
return 0;
}
For some odd reason, whenever there is a parantheses in the input expression, I get a segmentation fault.
My aim was to convert an infix expression to a postfix expression. I was trying to implement it using a stack.
Is it because I am passing the stack from a called function to other functions?
else if(c==')')
{
while(c != '(')
pop(s);
pop(s);
}
If c is a ), it can't be a ( until you change its value. Inside that while loop, you don't change its value. So that will keep calling pop forever.
void pop(stack *s)
{
printf("%c ", s->data[s->top]);
s->top--;
}
This function has no safeties. If you pop when the stack is empty, it will read outside the bounds of s->data. So calling pop in an endless loop is a disaster.
I was trying to implement a stack. I came up with this. All the other functions work as expected except when is try to push. When i try to push 4 some thing strange happens.
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
typedef struct
{
int a[MAX];
int top;
}stack;
void init(stack *p)
{
p->top=-1;
}
int full(stack *p)
{
if(p->top==MAX)
return 1;
else
return 0;
}
int empty(stack *p)
{
if(p->top==-1)
{
init(p);
return 1;
}
else
return 0;
}
void display(stack *p)
{
if(!empty(p))
{
printf("Stack is::\n");
for(int i=0;i<=p->top;++i)
printf("%d\t",p->a[i]);
printf("\n");
}
else
{
printf("Stack is empty.\n");
init(p);
}
}
void push(stack *p, int x)
{
if(!full(p)) /*full() returns 1 is top==max, 0 otherwise*/
{
p->a[p->top++]=x;
printf("%d pushed.\n",x);
}
else
printf("Stack is full.\n");
}
void pop(stack *p)
{
if(!empty(p))
printf("%d popped.\n",p->a[p->top--]);
else
{
printf("Stack is empty.\n");
init(p);
}
}
int main()
{
stack p;
int ch,x;
printf("Hello world!\n");
init(&p);
printf("*****MENU*****\n");
do{
printf("1.Push\n2.Pop\n3.Display\n4.Exit\n");
printf("Enter your choice:: ");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("Enter element to push:: ");
scanf("%d",&x);
push(&p,x);
break;
case 2:
pop(&p);
break;
case 3:
display(&p);
break;
case 4:
exit(1);
}
}while(ch!=4);
return 0;
}
The program terminates.
I am testing the while loop with ch(=1) and not x(=4). So why is this happening??
This function
void push(stack *p, int x)
{
if(!full(p)) /*full() returns 1 is top==max, 0 otherwise*/
{
p->a[p->top++]=x;
printf("%d pushed.\n",x);
}
else
printf("Stack is full.\n");
}
is wrong. The initial value of top is -1 so in this statement
p->a[p->top++]=x;
you are trying to store the value in the element of the array with the index equal to -1.
Thus the program has undefined behaviour.
The function could look like
void push( stack *p, int x )
{
if ( !full( p ) ) /*full() returns 1 if top + 1 == max, 0 otherwise*/
{
p->a[++p->top]=x;
^^^^^^^^
printf("%d pushed.\n",x);
}
else
{
printf("Stack is full.\n");
}
}
Take into account that in this case function full should look like
int full( const stack *p )
{
return p->top + 1 == MAX;
^^^^^^^^^^
}
Function empty also can be written simpler
int empty( const stack *p )
{
return p->top == -1;
}
And a stack usually is printed in the reverse order relative to the order of entering elements
void display( const stack *p )
{
if ( !empty( p ) )
{
printf( "Stack is::\n" );
for ( int i = p->top; i != -1; --i )
printf( "%d\t", p->a[i] );
printf( "\n" );
}
else
{
printf( "Stack is empty.\n" );
}
}
I have implemented push pop and get minimum in O(1) complexity. I have seen many solutions in C++. This is an implementation in C itself. Is the following program correct?
#include <stdio.h>
#include <stdlib.h>
int stack[15],aux[15];
int top=-1,count=-1,aux_count=-1,temp_aux=-1;
void push_auxilary(int ele)
{
aux[++aux_count] = ele;
}
void push_stack(int ele)
{
stack[++top]=ele;
}
void push(int ele)
{
if(top < 0 && aux_count < 0)
{
push_auxilary(ele);
push_stack(ele);
}
else
{
if(ele > aux[aux_count])
{
push_auxilary(aux[aux_count]);
push_stack(ele);
}
else
{
push_stack(ele);
push_auxilary(ele);
}
}
}
int pop_stack()
{
return stack[top--];
}
int pop_auxilary()
{
return aux[aux_count--];
}
int pop()
{
int a = pop_stack();
pop_auxilary();
return a;
}
void display()
{
for (int i = top; i >= 0; i--)
{
printf("%d\n",stack[i]);
/* code */
}
}
int get_min()
{
return aux[aux_count];
}
int main(int argc, char const *argv[])
{
int i=0;
push(5);
push(9);
push(1);
push(6);
push(1);
push(54);
push(34);
push(9);
push(3);
push(4);
push(7);
push(12);
push(02);
printf("the %d\n",get_min() );
for (i = aux_count; i >= 0; i--)
{
printf("%d\n",aux[i]);
}
return 0;
}
Looks like it gets the job done in O(1) indeed. Algorithmic-ally correct, but terrible from code reusage point of view.