Ir ao conteúdo

Posts recomendados

Postado

Bom dia.

Estou com o seguinte problema, tenho um exercicio pra fazer, que é praticamente:

Pegar uma expressao INFIXA, como exemplo (4+2)*(6-4)

e tenho que converter para POS FIXA, tendo como resultado : 4 2 + 6 4 - *

E ter o resultado dessa expressao POSFIXA, que nesse exemplo seria = 12.

 

Li em vários lugares e consegui fazer, segue o codigo abaixo.

O problema é que ele converte para POSFIXA, e fiz uma funcao para calcular a expressao POSFIXA, porém não consigo pegar o resultado do POSFIXA e trazer para funcao calcular.

No codigo dá pra entender melhor. Deixei comentarios.

Se alguém puder ajudar

#include <stdio.h>
#include <stdlib.h>
#include "pilha.h"


int main()
{
    char expInfixa[] = "(7 + 3) * (6 - 4)";

    printf("\n\tExpressao INFIXA: %s \n\n", expInfixa);

    printf("\tExpressao POSFIXA: ");
    converteInPos(expInfixa); //Função para converter expressão
    //AGORA ESSA PARTE NÃO CONSEGUE OBTER O RESULTADO, POIS ESSA FUNCAO CALCULA NÃO CONSEGUE CALCULAR O AUX RECEBIDO, DA ALGUM ERRO
    printf("\n\tResultado: %.2f\n", calcula_expressao(expPosFixa));


    //QUANDO EU FAÇO DIGITANDO DAQUI EM DIANTE ELE MANDA O VALOR QUE EU DIGITO E CALCULA CERTINHO
    /*
    printf("\n\n\tDigite a expressao POSFIXA convertida acima: "); //Dar espeços para cada numero formado, Digitar da mesma forma a expressão convertida

    gets(expPosFixa);

    printf("\n\tResultado: %.2f\n", calcula_expressao(expPosFixa));

    */

    return 0;

}
//arquivo pilha.c

struct lista
{
    float info;
    struct lista *proximo;
};

typedef struct no{    //Struct NO para RESOLVER EXPRESSÃO POSfIXA
    float valor;
    struct no *proximo;
    int n; //Numero de elementos
}No;

struct pilha
{
    Lista* prim;  //A pilha vai ser representada por um ponteiro para o primeiro no da lista
};

Pilha* criar_pilha()
{
    Pilha* p = (Pilha*)malloc(sizeof(Pilha));
    p->prim = NULL;
    return p;
}

void push(Pilha* p, float v)
{
    Lista *n = (Lista*)malloc(sizeof(Lista)); //N = novo
    n->info = v;
    n->proximo = p->prim;
    p->prim = n;
}

float pop(Pilha* p)
{
    Lista* t;
    float v;
    if(vazia(p))
    {
        printf("Pilha Vazia");
        exit(1);
    }
    t = p->prim;
    v = t->info;
    p->prim = t->proximo;
    free(t); //Acertar o encadeamento

}

int vazia(Pilha* p)
{
    return(p->prim == NULL);
}

void liberar(Pilha* p)
{
    Lista *q = p->prim;
    while(q!=NULL)
    {
        Lista *t = q->proximo; //Foi guardado em q, logo libero o Q
        free(q);
        q = t; //Para liberar todos elementos da lista
    }
    free(p);
}

float topo(Pilha* p)
{
    if(vazia(p))
    {
        printf("Pilha Vazia");
        exit(1);
    }
    return p->prim->info;
}

//CONVERTER PILHA

void converteInPos(char expressao[]){
    Pilha *p;
    int i = 0;
    int cont = 0;
    int max; //QTD de caractere
    char caractere,caracTemp;
    char aux[max]; //Guarda expressão
    char espaco = ' ';
    //char aux2[50];

    p = criar_pilha();
    push(p, '(');

    do{
        caractere = expressao[i]; //Recebe a Expressao "(7 + 3)*(6 -  4)";
        i++;

        if(caractere >= '0' && caractere <= '9'){
            printf("%c", caractere);
            aux[cont] = caractere;
            printf("%c", espaco);
            //printf("[%c]", aux[cont]); //TESTES
            cont++;
            aux[cont] = espaco;
            //printf("[%c]", aux[cont]); //TESTES
            cont++;
        }
        else if(caractere == '(' ){
            push(p, '('); //Coloco "(" na pilha
        }
        else if(caractere == '+' || caractere == '-' || caractere == '*' || caractere== '/')
        {
            while(1){
                caracTemp = pop(p);
                if(prioridades(caractere,caracTemp)){
                    push(p, caracTemp);
                    push(p, caractere);
                    break;
                }
                else
                {
                    printf("%c", caracTemp);
                }
            }
        }
        else if(caractere == ')' || caractere == '\0'){
            do{
                caracTemp = pop(p); //Tira da pilha o "("
                if(caracTemp != '(')
                printf("%c", caracTemp); //Imprime sinais
                if(caracTemp == '+' || caracTemp == '-') //Recebe + ou -
                {
                    aux[cont] = caracTemp ;
                    printf("%c", espaco);
                    cont++;
                    aux[cont] = espaco;
                    cont++;
                }
                else if(caracTemp == '*' || caracTemp == '/')
                {
                    aux[cont] = caracTemp;
                   // printf("TESTE%c", aux[cont]);
                    cont++;
                    aux[cont] = espaco;
                    cont++;
               }
            }while(caracTemp != '(');
        }

    }while(caractere != '\0');

    //max = cont ; //Contador de caractere , inclui espaço
    //printf("\n\nMAX = %d", max); //Teste
    //printf("\n\n\nAUX[i] : %s\n", aux);
/*
    for(cont=0;cont<max;cont++)
    {
        printf("%c",aux[cont]);
    }
    printf("\n");
*/

 char t[] = "7 3 + 6 4 - *";

 printf("\n\n\nResultado: %s \n",calcula_expressao(t)); //QUANDO EU PASSO T PARA FUNCAO CALCULAR, NÃO CALCULA, USEI T COMO TESTE
                                                        //MAS NA REALIDADE QUERIA PEGAR O AUX E PASSAR PRA LÀ< POIS AUX RECEBE O RESULTADO DA CONVERSAO

    //return aux;
    liberar(p);
}

int prioridades(char carac1, char carac2){

    int pCarac1,pCarac2;

    if(carac1 == '*' || carac1== '/'){
        pCarac1 = 3;
    }
    else if(carac1 == '+' || carac1 == '-'){
        pCarac1 = 2;
    }
    else if(carac1 == '('){
        pCarac1 = 1;
    }
    if(carac2 == '*' || carac2 == '/'){
        pCarac2 = 3;
    }
    else if(carac2 == '+' || carac2 == '-'){
        pCarac2 = 2;
    }
    else if(carac2 == '('){
        pCarac2 = 1;
    }

    return (pCarac1 > pCarac2);
}

//RESOLUÇÃO Expressao

No* desempilhar(No **pilha){
    No *remover = NULL;

    if(*pilha){                      //Se o conteúdo apontado por esse ponteiro for diferente de Nulo
        remover = *pilha;            //Recebe o topo da pilha
        *pilha = remover->proximo;   //Remove do topo da pilha
    }
    else
        printf("\tPILHA VAZIA\n");
    return remover;
}

No* empilhar(No *pilha, float num){
    No *novo = malloc(sizeof(No));

    if(novo){
        novo->valor = num;
        novo->proximo = pilha;
        return novo;
    }
    else
        printf("\tErro ao alocar memória!\n");
    return NULL;
}

float calculo(float a, float b, char exp){
    switch(exp){
    case '+':
        return a+b;
        break;
    case '-':
        return a-b;
        break;
    case '/':
        return a/b;
        break;
    case '*':
        return a*b;
        break;
    default:
        return 0.0;
    }
}

float calcula_expressao(char expressao[]){

    char *ptrExp; //ponteiro que recebe expressao
    float resultado;
    No *elem1, *elem2; //Elementos para desempilhar os sinais da pilha
    No *pilha = NULL;
    Pilha *p;

    printf("\nTestando recebimento: %s", expressao);

    ptrExp = strtok(expressao," "); //Recebe uma string e consegue dividílas em espaço, pois está " ";
    while(ptrExp){
        if(ptrExp[0] == '+' || ptrExp[0] == '-' || ptrExp[0] == '/' || ptrExp[0] == '*'){
            elem1 = desempilhar(&pilha);
            elem2 = desempilhar(&pilha);
            resultado = calculo(elem2->valor, elem1->valor, ptrExp[0]);
            pilha = empilhar(pilha, resultado);
            free(elem1);
            free(elem2);
        }
        else{
            resultado = strtol(ptrExp, NULL, 10); //funcao para converter string para decimal, utiliza NULL pois já está divido os números por espaços.
            pilha = empilhar(pilha, resultado);
        }
        ptrExp = strtok(NULL," "); //devolve um ponteiro para a próxima palavra na string apontada
    }
    elem1 = desempilhar(&pilha);
    resultado = elem1->valor;
    free(elem1);

    return resultado;
}
//arquivo piha.h

typedef struct lista Lista;
typedef struct pilha Pilha;
typedef struct no No;

Pilha* criar_pilha();//Aloca dinamicamente a estrutura da pilha e inicializar os campos e retornar seus pontreiros
void push(Pilha* p, float v); //Inserir
float pop(Pilha* p);//Remover
int vazia(Pilha* p);//Verifica se está vazia
void liberar(Pilha* p);//Liberar o que foi alocado
float topo(Pilha* p);

void converteInPos(char expressao[]);
int prioridades(char c, char t);

float calcula_expressao(char expressao[]);
float calculo(float a, float b, char exp);
No* empilhar(No *pilha, float num);
No* desempilhar(No **pilha);
void teste(char teste[]);

 

Gostaria de dicas de otimização, como deixar bem mais estruturado.

AGradeço demais.

  • Obrigado 1
Postado

Ola!

Em 23/04/2022 às 13:00, Lipeco disse:

não consigo pegar o resultado do POSFIXA e trazer para funcao calcular

            Consegue converter e mostrar o resultado  duma pessoalmente, isso é: sem eletrificar|construir|codificar em c, somente via notepad ou (papel e lápis) com base em lógica de operações de pilha?

Sendo elas:

  • empilhar(stack,push)
  • desempilhar(stack,pop)

Isso não é realmente necessário, mas esclarecerá o problema.

Veja:

Em 23/04/2022 às 13:00, Lipeco disse:

(4+2)*(6-4)

Em 23/04/2022 às 13:00, Lipeco disse:

4 2 + 6 4 - *

            Acima, eu observo as pilhas: operadores, operandos, tradução e adequação, sendo essa última a tradução na ordem de entrada. Ou seja, eu espero que no fim da tradução a expressão fique na ordem inversa do formato de entrada, desse jeito:

 

[* - 4 6 + 2 4]

Assim, ao desempilhar tradução em adequação terei uma pilha na ordem inversa dos itens (acima): sendo a ordem do formato de entrada, desse jeito:

[4 2 + 6 4 - *]

            Sei também que o operador adição (+) ficou em seguida dos operandos (4 e 2) porque durante a tradução abriu e fechou parenteses, isso é, todos os operadores exceto e antes do abre, que estão na pilha de operadores, foram desempilhados para tradução, nesse caso foi somente  o operador adição (+) e, logicamente, os [abre e fecha] parenteses são descartes.

 

É isso,@Lipeco ?

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!