Pilhas em C: Uma Abordagem Prática com Duas Pilhas de Caracteres: Exemplo De Programa Em C Com 2 Pilhas Em Char

Exemplo De Programa Em C Com 2 Pilhas Em Char – Este artigo apresenta uma implementação em C de duas pilhas utilizando arrays, abordando desde conceitos básicos de estruturas de dados até o tratamento de erros e considerações de eficiência. Exploraremos a aplicação prática dessas pilhas na verificação de palíndromos, demonstrando a versatilidade e utilidade dessa estrutura de dados fundamental em programação.

Introdução à Estrutura de Dados Pilha

Exemplo De Programa Em C Com 2 Pilhas Em Char

Uma pilha é uma estrutura de dados linear que segue o princípio LIFO (Last-In, First-Out), ou seja, o último elemento inserido é o primeiro a ser removido. Imagine uma pilha de pratos: você só pode adicionar um prato no topo e remover o prato do topo. As pilhas são amplamente utilizadas em diversas aplicações, como gerenciamento de memória, avaliação de expressões aritméticas, e controle de fluxo em programas, entre outras.

A principal diferença entre pilhas e filas reside no mecanismo de acesso aos elementos. Enquanto as pilhas seguem o princípio LIFO, as filas seguem o princípio FIFO (First-In, First-Out), similar a uma fila de espera: o primeiro elemento inserido é o primeiro a ser removido.

Em C, uma pilha pode ser implementada utilizando arrays. Um array é alocado para armazenar os elementos da pilha, e um índice acompanha o topo da pilha, indicando a posição do último elemento inserido. Operações como inserção (push) e remoção (pop) são realizadas nesse array, mantendo a ordem LIFO.

Implementação de Duas Pilhas em Char

O programa a seguir demonstra a criação e manipulação de duas pilhas de caracteres utilizando um único array. Um índice controla o topo de cada pilha, permitindo que ambas compartilhem o mesmo espaço de memória sem sobreposição. O limite de tamanho do array é definido, garantindo a prevenção de estouro de pilha (stack overflow).

A tabela a seguir ilustra o estado das pilhas após cada operação. Observe que o tamanho máximo do array é considerado, e mensagens de erro são exibidas caso ocorra estouro ou vazamento de pilha.

Operação Pilha 1 Pilha 2 Status
Push ‘A’ na Pilha 1 A Pilha 1: Não Cheia, Pilha 2: Vazia
Push ‘B’ na Pilha 1 AB Pilha 1: Não Cheia, Pilha 2: Vazia
Push ‘X’ na Pilha 2 AB X Pilha 1: Não Cheia, Pilha 2: Não Vazia
Pop da Pilha 1 A X Pilha 1: Não Vazia, Pilha 2: Não Vazia
Pop da Pilha 2 A Pilha 1: Não Vazia, Pilha 2: Vazia
Push ‘C’ na Pilha 1 (limite próximo) AC Pilha 1: Não Cheia, Pilha 2: Vazia
Push ‘D’ na Pilha 1 (pilha cheia!) AC Erro: Pilha 1 Cheia

Operações com as Pilhas: Push e Pop

As funções push e pop são fundamentais para a manipulação das pilhas. A função push adiciona um elemento ao topo da pilha, enquanto a função pop remove e retorna o elemento do topo. Ambas as funções incluem tratamento de erros para situações de pilha cheia ( push) e pilha vazia ( pop).

Funções auxiliares, pilha_cheia e pilha_vazia, verificam o estado das pilhas, facilitando o gerenciamento de erros.

Exemplo de Uso: Verificação de Palíndromo

Um palíndromo é uma sequência que pode ser lida da mesma forma de trás para frente, como “arara” ou “ovo”. Este exemplo demonstra como usar duas pilhas para verificar se uma string é um palíndromo. A string é inserida pelo usuário, e cada caractere é empilhado em uma das pilhas. Em seguida, os caracteres são desempilhados e comparados, verificando se são iguais.

Se todos os caracteres corresponderem, a string é um palíndromo.


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

#define MAX_TAM 100

// ... (implementação das funções push, pop, pilha_cheia, pilha_vazia) ...

int main() 
  char str[MAX_TAM];
  char pilha1[MAX_TAM], pilha2[MAX_TAM];
  int topo1 = -1, topo2 = -1;

  printf("Digite uma string: ");
  fgets(str, MAX_TAM, stdin);
  str[strcspn(str, "\n")] = 0; // remove o \n do fgets

  int len = strlen(str);
  for (int i = 0; i < len; i++) 
    char c = tolower(str[i]); //ignora maiúsculas/minúsculas
    if (isalpha(c))  // considera apenas letras
        push(pilha1, &topo1, c);
        push(pilha2, &topo2, c);
    
  

  int palindromo = 1;
  while (topo1 != -1) 
    if (pop(pilha1, &topo1) != pop(pilha2, &topo2)) 
      palindromo = 0;
      break;
    
  

  if (palindromo) 
    printf("'%s' é um palíndromo.\n", str);
   else 
    printf("'%s' não é um palíndromo.\n", str);
  

  return 0;


 

Tratamento de Erros e Exceções, Exemplo De Programa Em C Com 2 Pilhas Em Char

O tratamento de erros é crucial para a robustez do programa. Situações como estouro de pilha ( stack overflow), quando se tenta adicionar um elemento a uma pilha cheia, e vazamento de pilha ( stack underflow), quando se tenta remover um elemento de uma pilha vazia, devem ser tratadas adequadamente. Mensagens de erro claras e informativas devem ser exibidas ao usuário, indicando o tipo de erro e a ação necessária.

Diferentes estratégias de tratamento de erros podem ser empregadas, como o uso de códigos de retorno, exceções (se a linguagem o permitir), ou a verificação explícita das condições de erro antes de cada operação.

Considerações sobre Eficiência

A complexidade de tempo das operações push e pop em uma pilha implementada com arrays é O(1), ou seja, constante. Isso significa que o tempo de execução dessas operações não depende do tamanho da pilha. A complexidade de espaço é O(n), onde n é o tamanho máximo da pilha, pois o array precisa alocar espaço para todos os elementos.

Comparando com outras implementações, como listas encadeadas, a implementação com arrays oferece melhor desempenho para operações de acesso aleatório, mas a lista encadeada permite um tamanho dinâmico, enquanto o array tem tamanho fixo.

Utilizar arrays para implementar pilhas apresenta vantagens como simplicidade e eficiência para operações de push e pop. No entanto, a desvantagem principal é a alocação de memória estática, o que limita o tamanho da pilha.

Extensões e Melhorias

Exemplo De Programa Em C Com 2 Pilhas Em Char

Para tornar o programa mais robusto, a adição de funcionalidades como a verificação de tamanho de entrada antes da alocação de memória e a implementação de uma pilha com tamanho dinâmico utilizando alocação de memória dinâmica ( malloc e realloc) são recomendadas. Uma função para visualizar o conteúdo das pilhas a qualquer momento também aumentaria a utilidade do programa.

A implementação de uma pilha com tamanho dinâmico permite que a pilha cresça ou diminua conforme necessário, eliminando a restrição de tamanho fixo dos arrays.

Dominar a arte de manipular pilhas em C é um passo importante na jornada de qualquer programador. Neste guia, percorremos a construção de um programa que utiliza duas pilhas de caracteres, abordando desde a implementação básica até o tratamento de erros e a otimização do código. Aprendemos a lidar com situações de pilha cheia e vazia, garantindo a robustez da aplicação.

A utilização prática na verificação de palíndromos serviu como um exemplo concreto da utilidade das pilhas. Esperamos que este tutorial tenha sido útil e que você possa agora aplicar esses conhecimentos para criar programas mais eficientes e robustos. Lembre-se: a prática leva à perfeição! Continue explorando o mundo da programação e aperfeiçoe suas habilidades.

Categorized in:

Uncategorized,

Last Update: February 2, 2025