aula 231

Verificar se uma expressão matemática está mal formada com uma PILHA

Nesta aula vamos ver uma aplicação da estrutura de dados pilha aqui no nosso Curso de Programação C. Vamos ver como verificar se uma expressão matemática está mal formada com o auxilio de uma estrutura PILHA.

Normalmente uma expressão matemática pode ser composta por caracteres como parênteses ( () ), colchetes ( [] ) e chaves ( {} ). Estes caracteres ajudam a determinar a ordem em que as operações podem ser realizadas. Para cada caracter de abertura é necessário um de fechamento formando o par.

A ideia aqui é elaborar um pequeno programa em C que, dada uma expressão digitada no teclado, ele seja capaz de dizer se a expressão está bem formada ou não.

No início pode parecer complicado, mas não é, desde claro que você tenha entendido como trabalhar com a estrutura pilha. A ideia básica aqui é, percorrer a expressão procurando pelos caracteres mencionados acima. Ao encontrar qualquer um dos três, vamos avaliar se é de abertura ou de fechamento. Se for de abertura, então ele será inserido na pilha. Se for de fechamento, então iremos remover o elemento do topo da pilha, que precisa obrigatoriamente fazer par com o elemento de fechamento, caso contrário a expressão está mal formada. Observe a expressão a seguir:

3 * [(5 – 2) / 5]

Será empilhado um [ e, sem seguida um (. Ao encontrarmos o ), será desempilhado o topo da pilha, formando o par (), e ao encontrar o ], será desempilhado novamente o topo da pilha, formando o par []. Como ao terminar a expressão a pilha estará vazia, então podemos afirmar que a expressão está bem formada.

Este processo descrito acima é realizado pela função a seguir:

int identifica_formacao(char x[]){
    int i = 0;
    No *remover, *pilha = NULL;

    // percorre a string (expressão digitada) até o fim
    while(x[i] != '\0'){
        // se for um caracter de abertura, empilha
        if(x[i] == '[' || x[i] == '(' || x[i] == '{'){
            pilha = empilhar(pilha, x[i]);
            imprimir(pilha);
        }
        // se for um caracter de fechamento, desempilha e verifica se formam par
        else if(x[i] == ']' || x[i] == ')' || x[i] == '}'){
            remover = desempilhar(&pilha);
            // se não formar um par, então a expressão está mal formada
            if(forma_par(x[i], remover->caracter) == 0){
                printf("\tEXPRESSAO MAL FORMADA!\n");
                return 1; // expressao está mal formada
            }
            free(remover);
        }
        i++;
    }
    imprimir(pilha);
    // ao final, se a pilha não estiver vazia significa que a expressão está mal formada
    if(pilha){
        printf("\tExpressao mal formada!\n");
        return 1;
    }
    else{
        printf("\tEXPRESSAO BEM FORMADA!\n");
        return 0;
    }
}

* Esta função tem um problema. Teste ela com esta expressão 3 * (5 – 2) / 5] e tende descobrir qual o problema. Nas aulas seguintes trarei a solução.

A função a seguir, utilizada na função anterior, recebe dois caracteres e verifica se formam um par ou não.

int forma_par(char f, char d){
    switch(f){
    case ')':
        if(d == '(')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    case ']':
        if(d == '[')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    case '}':
        if(d == '{')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    }
}

Código completo em C para verificar se uma expressão está bem formada ou não com uma estrutura de dados pilha

/*
            Aula 231: Como descobrir se uma expressão matemática está mal formada?

            Código escrito por Wagner Gaspar
            Julho de 2021
*/

typedef struct no{
    char caracter;
    struct no *proximo;
}No;

No* empilhar(No *pilha, char valor){
    No *novo = malloc(sizeof(No));

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

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

    if(*pilha){
        remover = *pilha;
        *pilha = remover->proximo;
    }
    else
        printf("\tPilha vazia\n");
    return remover;
}

void imprimir(No *pilha){
    printf("\n\tPILHA\n");
    while(pilha){
        printf("\t%c\n", pilha->caracter);
        pilha = pilha->proximo;
    }
    printf("\tFIM PILHA\n\n");
}

int forma_par(char f, char d){
    switch(f){
    case ')':
        if(d == '(')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    case ']':
        if(d == '[')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    case '}':
        if(d == '{')
            return 1; // bem formada
        else
            return 0; // mal formada
        break;
    }
}

int identifica_formacao(char x[]){
    int i = 0;
    No *remover, *pilha = NULL;

    while(x[i] != '\0'){
        if(x[i] == '[' || x[i] == '(' || x[i] == '{'){
            pilha = empilhar(pilha, x[i]);
            imprimir(pilha);
        }
        else if(x[i] == ']' || x[i] == ')' || x[i] == '}'){
            remover = desempilhar(&pilha);
            if(forma_par(x[i], remover->caracter) == 0){
                printf("\tEXPRESSAO MAL FORMADA!\n");
                return 1; // expressao está mal formada
            }
            free(remover);
        }
        i++;
    }
    imprimir(pilha);
    if(pilha){
        printf("\tExpressao mal formada!\n");
        return 1;
    }
    else{
        printf("\tEXPRESSAO BEM FORMADA!\n");
        return 0;
    }
}

int main(){
    char exp[50];

    printf("\tDigite um expressao: ");
    scanf("%49[^\n]", exp);
    printf("\nExpressao: %s\nRetorno: %d\n", exp, identifica_formacao(exp));
}

Deixe um comentário

vinte − 8 =

Wagner Gaspar

Capixaba de São Gabriel da Palha, Espírito Santo. Bacharel em Ciência da Computação pela Universidade Federal do Amazonas e mestre em informática pela Universidade Federal do Espírito Santo.