Underc0de

Programación General => C / C++ => Códigos Fuentes => Mensaje iniciado por: Juan en Noviembre 12, 2013, 08:41:11 PM

Título: Resolver expresiones con pilas
Publicado por: Juan en Noviembre 12, 2013, 08:41:11 PM
Resuelve expresiones como 1+1+1+1 , 2*5(3+4), (5*2)+(5*3). No resolvera numeros de dos o mas caracteres, aunque modificando un poco el codigo se puede conseguir :)

un saludo!

// convierte expresion INFIJA en POSTFIJA y evalua expresiones POSTFIJAS
// programado por Juan fary (mDrinky) [email protected]
// compilado con MingW y Code::Blocks

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Dato
{
    char caracter;
    struct Dato * Siguiente;
}_Dato;

typedef _Dato * ptrDato;

void push(ptrDato * Pila,char caracter);
char pop(ptrDato * Pila);
int Prioridad(char Op1,char Op2);
char * PostFija(char * Cadena);
int Evaluar(char * Expresion);

int main()
{
    char * cadena = "5*3+8*5";

    char * Expresion = PostFija(cadena);

    printf("POSTFIJA: %s\n",Expresion);

    printf("Resultado de la operacion: %i",Evaluar(Expresion));

    return 0;
}

int Evaluar(char * Expresion)
{
    ptrDato Pila = NULL;
    int num1 = 0,num2 = 0,i = 0, Resultado = 0;

    while (Expresion[i] != '\0')
    {
        if (Expresion[i] != '*' && Expresion[i] != '/' && Expresion[i] != '+' && Expresion[i] != '-')
        {
            push(&Pila,Expresion[i]);
        }else{
            num1 = (pop(&Pila)-0x30);
            num2 = (pop(&Pila)-0x30);

            switch (Expresion[i])
            {
                case '*':
                    Resultado = ((num1*num2));
                    break;

                case '/':
                    Resultado = ((num1/num2));
                    break;

                case '+':
                    Resultado = ((num1+num2));
                    break;

                case '-':
                    Resultado = ((num1-num2));
                    break;
            }
            push (&Pila,(Resultado+0x30));
        }
        i++;
    }
    return Resultado;
}

char * PostFija(char * cadena)
{
    ptrDato Pila = NULL;
    int i = 0,a = 0, Elementos = 0,Longitud = 0;
    char dato;

    Longitud = strlen(cadena);

    char * buffer = (char*) malloc(Longitud);
    memset(buffer,0,Longitud);

    while(cadena[i] != '\0')
    {
        if (cadena[i] == '(')
        {
            push(&Pila,cadena[i]);
            Elementos += 1;
        }else if (cadena[i] == ')'){
            while(1)
            {
                dato = pop(&Pila);
                Elementos -= 1;

                if(dato == '(')
                {
                    break;
                }else{
                    buffer[a] = dato;
                    a += 1;
                }
            }
        }else if(cadena[i] == '*' || cadena[i]  == '/' || cadena[i] == '+' || cadena[i] == '-'){
            RepetirProceso:
            if (Elementos == 0)
            {
                push (&Pila,cadena[i]);
                Elementos += 1;
            }else if(Prioridad(Pila->caracter,cadena[i]) == 1)
            {
                push(&Pila,cadena[i]);
                Elementos += 1;
            }else if (Pila->caracter != '('){
                dato = pop(&Pila);
                Elementos -= 1;

                buffer[a] = dato;
                a += 1;

                goto RepetirProceso;
            }
        }else{
            buffer[a] = cadena[i];
            a += 1;
        }
        i++;
    }

    while(Pila != 0)
    {
        buffer[a] = pop(&Pila);
        a += 1;
    }
    return buffer;
}

int Prioridad(char Op1,char Op2)
{
        int Estado = 1;

        if (Op1 == '*' && Op2 == '-' || Op1 == '*' && Op2 == '+' || Op1 == '/' && Op2 == '-' || Op1 == '/' && Op2 == '+')
        {
            Estado = 0;
        }

        return Estado;
}

char pop(ptrDato * Pila)
{
    ptrDato ViejoDato;
    char _caracter;

    ViejoDato = *Pila;
    _caracter = (*Pila)->caracter;

    *Pila = (*Pila)->Siguiente;

    free(ViejoDato);

    return _caracter;
}
void push(ptrDato * Pila,char caracter)
{
    ptrDato NuevoDato;

    NuevoDato = (ptrDato)malloc(sizeof(_Dato));
    memset(NuevoDato,0,sizeof(_Dato));

    if (NuevoDato != NULL)
    {
        NuevoDato->caracter = caracter;
        NuevoDato->Siguiente = *Pila;

        *Pila = NuevoDato;
    }
}
Título: Re:Resolver expresiones con pilas
Publicado por: ANTRAX en Noviembre 13, 2013, 09:12:15 AM
Muy bueno mDrinky!
Cuando dices que no resuelve numeros con dos caracteres, tambien te refieres a numeros decimales?

Saludos!
Título: Re:Resolver expresiones con pilas
Publicado por: 79137913 en Noviembre 13, 2013, 09:33:45 AM
HOLA!!!

Quiere decir que su metodo toma a cada caracter como numero completo no como digitos de un numero mas grande...

Osea:
923 seria para su procedimiento 9 ; 2 ; 3

y 9,23 seria para su procedimiento 9 ; , ; 2 ; 3

GRACIAS POR LEER!!!
Título: Re:Resolver expresiones con pilas
Publicado por: Stiuvert en Noviembre 13, 2013, 09:36:44 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Cuando dices que no resuelve numeros con dos caracteres, tambien te refieres a numeros decimales?

Seguramente no los aceptará Antrax.

Porque esta usando números enteros (Int), para que aceptará números decimales tendría que usar "float".


Saludos
Título: Re:Resolver expresiones con pilas
Publicado por: ANTRAX en Noviembre 13, 2013, 09:42:40 AM
Tienen razon! ahi lo lei!
Ahora si vale la aclaracion de mDrinky

CitarNo resolvera numeros de dos caracteres, aunque modificando un poco el codigo se peude conseguir
Título: Re:Resolver expresiones con pilas
Publicado por: 79137913 en Noviembre 13, 2013, 10:31:23 AM
HOLA!!!

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Cuando dices que no resuelve numeros con dos caracteres, tambien te refieres a numeros decimales?

Seguramente no los aceptará Antrax.

Porque esta usando números enteros (Int), para que aceptará números decimales tendría que usar "float".


Saludos

Lamento decir que esa apreciacion es erronea, se puede operar con enteros y para calcular decimales... simplemente se realiza una simulacion de coma flotante donde se multiplica el numero por una potencia de diez grande, luego se realizan las opreaciones y por ultimo se vuelve a dividir...

Ejemplo:
9,7*8,2=> ((9,7*10)*(8.2*10))=>7954 /100 = 79.54
Ahora ustedes me diran, usaste punto en la ultima division...
NO, se hace asi la cuenta:
Int(7954/100)=79 (aca sabemos que la parte entera es 79, eso lo guardamos
79*100 = 7900 ...  7954-7900 = 54 (la parte decimal)

de esta manera ponemos 79 , 54 y no utilizamos decimales ;)

GRACIAS POR LEER!!!
Título: Re:Resolver expresiones con pilas
Publicado por: Juan en Noviembre 13, 2013, 11:17:36 AM
Es lo que dice 7913,  He actualizado el código corrigiendo y minimizando algunas cosillas :P