CrappyCoder CrappyCoder - 1 month ago 14
C Question

Trouble using push in stack

I'm learning data structures and I have a problem pushing data into my stack. Even though I have used the same push function early in the program it doesn't seem to push characters. The program should transform infix expressions to postfix

When given the number "1+2" it should return "12+", however it only returns "12"
Thanks in advice

bool revisar(char * inf, stack p){
inicializa(&p);
Nodo D;
char pos[MAX];
int i=0;
int j=0;
while(inf[i]!='\0')
{//WHILE
if(inf[i]>='0' && inf[i]<='9')
{
pos[j++]=inf[i++];
}
if(inf[i]=='(')
{
D.caracter=inf[i++];
push(&p,D);
}
if(inf[i]==')')
{

while(top(p).caracter!='(')
{
pos[j++]=pop(&p).caracter;
}
if(top(p).caracter=='(')
pop(&p);
i++;
}
else
{
if(inf[i]=='+'||inf[i]=='-'||inf[i]=='*'||inf[i]=='/')
{
if(empty(p)||top(p).caracter=='(')
{
D.cara

cter=inf[i++];
push(&p,D);
if(empty(p));
printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); **Here it prints that the stack is still empty....
}
else
{
if(menorpre(top(p).caracter,inf[i]))
{
D.caracter=inf[i++];
push(&p,D);
}
else
{
pos[j++]=pop(&p).caracter;
if(!empty(p))
{
if(top(p).caracter!='(')

pos[j++]=pop(&p).caracter;
}
else
{
D.caracter=inf[i++];
push(&p,D);
}
}
}
}
}
}
while(!empty(p)){
printf("ddd");
pos[j++]=pop(&p).caracter;
}
pos[j]='\0';

printf("\n \n");
printf("i=%d,j=%d",i,j);
printf("LA CADENA EN POSFIJO ES: ");
puts(pos);
}


My stack library

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include "pila.h"

void inicializa(stack *p ){
*p = NULL;
}

bool empty(stack p){
if (p==NULL){
return true;
}
else return false;
}

int push(stack * p, Nodo n){
stack nuevo = (stack)malloc(sizeof(Nodo));
if(nuevo == NULL){
return 300;
}
*nuevo = n;
if(empty(*p)){
nuevo->next = NULL;
}
else{
nuevo->next = *p;
*p = nuevo;
}
return 301;
}


Nodo pop(stack * p){
Nodo copy = *(*p);
free(*p);
*p = copy.next;
inicializa(&copy.next);
return copy;
}

Nodo top(stack p){
Nodo copy;
copy = *p;
copy.next = NULL;
return copy;
}


The header file

struct nodo{
char caracter;
int numero;
struct nodo * next;
};
typedef struct nodo Nodo;
typedef Nodo * stack;
void inicializa(stack *p);
bool empty(stack p);
Nodo top(stack p);
Nodo pop(stack *p);
int push(stack *p, Nodo n);

Answer

The short answer -- in this code:

int push(stack * p, Nodo n){
    stack nuevo = (stack)malloc(sizeof(Nodo));
    if(nuevo == NULL){
        return 300;
    }
    *nuevo = n;
    if(empty(*p)){
        nuevo->next = NULL;
        }
    else{
        nuevo->next = *p;
    *p = nuevo;
    }
    return 301;
}

The *p = nuevo; should come after the else, not inside it. It applies regardless. The longer answer:

There are several problems with your stack code, including mismanagement of malloc'd memory. I suggest a simpler stack design, along the lines:

struct nodo {
    char caracter;
    struct nodo *next;
};

typedef struct nodo Nodo;
typedef Nodo *stack;

void inicializa(stack *p);
bool empty(stack p);
char top(stack p);
char pop(stack *p);
int push(stack *p, char c);

void inicializa(stack *p) {
    *p = NULL;
}

bool empty(stack p) {
    return (p == NULL);
}

int push(stack *p, char caracter) {
    Nodo *nuevo = malloc(sizeof(*nuevo));

    if (nuevo == NULL) {
        return 300;
    }

    nuevo->caracter = caracter;

    if (empty(*p)) {
        nuevo->next = NULL;
    } else {
        nuevo->next = *p;
    }

    *p = nuevo;

    return 301;
}

char pop(stack *p) {
    Nodo *copy = *p;

    *p = copy->next;

    char caracter = copy->caracter;

    free(copy);

    return caracter;
}

char top(stack p) {
    return p->caracter;
}

This requires a revision of revisar() along the lines:

void revisar(char *inf, stack p)
{
    char caracter;
    char pos[MAX];
    int i = 0;
    int j = 0;

    inicializa(&p);

    while (inf[i] != '\0')
    {
        if (inf[i] >= '0' && inf[i] <= '9')
        {     
            pos[j++] = inf[i++];     
        }
                else if(inf[i] == '(')
                {     
                      (void) push(&p, inf[i++]);    
                }
                else if (inf[i] == ')')
                {
            while (top(p) != '(')
            {
                pos[j++] = pop(&p);                 
            }

            if (top(p) == '(')
            {
                (void) pop(&p);
            }

            i++;   
        }
                else
        {
            if (inf[i] == '+' || inf[i] == '-' || inf[i] == '*' || inf[i] == '/')
            {
                if (empty(p) || top(p) == '(')
                {   
                    (void) push(&p, inf[i++]);

                    if (empty(p))
                    {
                        printf("NNNNNNOOOOOOOOOOOOOOOOOOOOOO"); // Here it prints that the stack is still empty....
                    }
                }
                else
                {
                    if (menorpre(top(p), inf[i]))
                    {
                        (void) push(&p, inf[i++]); 
                    }
                    else
                    {
                        pos[j++] = pop(&p);

                        if (!empty(p))
                        {
                            if (top(p) != '(')
                            {
                                pos[j++] = pop(&p);
                            }
                        }
                        else
                        {   
                            (void) push(&p, inf[i++]);
                        }
                    }
                }
            }
        }
    }

        while (!empty(p))
    {
        pos[j++] = pop(&p);  
    }

    pos[j]='\0';

    printf("\n \n");
    printf("i=%d, j=%d", i, j);
    printf("LA CADENA EN POSFIJO ES: ");
    puts(pos); 
}

In my testing, I was able to get revisar("1+2", p); to produce:

% ./a.out
ddd

i=3, j=3LA CADENA EN POSFIJO ES: 12+
%

Which I'm guessing is what you're after. If you have more questions about this, make sure to add the definition of menorpre() to your code above as it's the piece that's missing that can't be reconstructed.

Comments