Ir para o conteúdo

Classes: Pilhas e Filas

Vou apresentar outro exemplo de classes. Desta vez, tem a ver com pilhas e filas e inclui tratamento de erros.

Agora um exemplo de pilhas genérica, em que podemos usar qualquer tipo de dados!

PilhaGenerica.cpp:

#include <iostream>

using namespace std;

//------------------- ERRO ------------------------------

class Erro_na_pilha
{
public:
  Erro_na_pilha(){};
  virtual void print_erro() const {cerr<<"Erro na Pilha!"<<endl;}
};


class Cheia:public Erro_na_pilha
{
public:
  Cheia(){};
  virtual void print_erro() const {cerr<<"A pilha esta cheia."<<endl;}
};


class Vazia:public Erro_na_pilha{
public:
  Vazia(){};
  virtual void print_erro()const {cerr<<"A pilha esta vazia."<<endl;};
};


// --------------- PILHA --------------------------

template <class C, const int maximo>

class Pilha
{
private:
  struct no_pilha
  {
    C* elem;
    no_pilha* ponta;
  };
  int n_elem;
  no_pilha* topo;
public:

  Pilha(){topo=NULL;n_elem=0;}

  virtual int get_maximo(){return maximo;}

  virtual int get_n_elem(){return n_elem;}


  virtual void push(C &i)
  { 
   if (n_elem<maximo)
      {
       no_pilha* novo=new no_pilha;
       novo->elem=&i;
       novo->ponta=topo;
       topo=novo;
       n_elem++;
      }
    else
      throw Cheia();

  }


  virtual C* pop()
  { if (topo!=NULL)
      {
    no_pilha* aux=new no_pilha;
    aux=topo;
    topo=topo->ponta;
    C* removido=(aux->elem);
    delete aux;
    n_elem--;
    return removido;
      }
    else
      throw Vazia();
  }


  virtual void printpilha()
  { 
    if (topo!=NULL)
    {
       no_pilha* aux= new no_pilha;
       aux=topo;
       int contador=n_elem;
       cout <<endl<<"________Os elementos da Pilha :_______ "<<endl<<endl;
       while (aux!=NULL)
       {
         cout<<contador<<") ";
         contador--;
         aux->elem->print();
         aux=(aux->ponta);
         cout<<endl;
       }
      cout<<endl;
     }

    else
      throw Vazia();
  }

  virtual void elimina_na_base()
  {
    Pilha <C, maximo> copiapilha;
    while (n_elem>0)
    {
        copiapilha.push(*pop());
    }

    copiapilha.pop();

    while (copiapilha.get_n_elem()>0)
    {
       push(*copiapilha.pop());
    }
  }
};

UsarPilhaGenerica.cpp:

#include <iostream>
#include "Ponto.cpp"
#include "PilhaGenerica.cpp"
using namespace std;

int main()
{
  Pilha<Par,10> pilhaA;
  int opcao=1;
  cout<<endl;
  cout<<endl;
  while (opcao!=0)
    { cout<<"\t################################"<<endl;
      cout<<"\t# Escolha a opção:             #"<<endl;
      cout<<"\t# 1) Adicionar Par na pilha.   #"<<endl;
      cout<<"\t# 2) Adicionar Ponto na pilha. #"<<endl;
      cout<<"\t# 3) Remover elemento do topo. #"<<endl;
      cout<<"\t# 4) Listar elementos da pilha.#"<<endl;
      cout<<"\t# 0) Sair.                     #"<<endl;
      cout<<"\t################################"<<endl;
      cout<<endl;
      cout<<endl;
      cin>>opcao;
      switch (opcao)
    {
    case 0:
      { cout<<"Adeus..."<<endl<<endl;
        break;
      }
    case 1:
      {  
        cout<<"Coordenadas do tipo Par:"<<endl<<"->";
        double a;
        double b;
        cin>> a;
        cout<<"=>";
        cin>> b;

        Par*Pr= new Par;
        (*Pr).set_left(a);
        (*Pr).set_right(b);

        try {pilhaA.push(*Pr);}

        catch (Erro_na_pilha &E)
        {
            E.print_erro();
            pilhaA.elimina_na_base();
            pilhaA.push(*Pr);
        }

        break;
      }
    case 2:
      {
        cout<<"Coordenadas do tipo Ponto:"<<endl<<"->";
        double x;
        double y;
        cin>> x;
        cout<<"=>";
        cin>> y;

        Ponto*Pt=new Ponto;
        (*Pt).set_left(x);
        (*Pt).set_right(y);

        try {pilhaA.push(*Pt);}

        catch (Erro_na_pilha &E)
        {
           E.print_erro();
           pilhaA.elimina_na_base();
           pilhaA.push(*Pt);
        }

        break;
      }
    case 3:
      {
        try{cout<<"Elemento ";pilhaA.pop()->print();cout<<" removido.\n\n";}
        catch (Erro_na_pilha &E){E.print_erro();}
        break;
      }
    case 4:
      { 
        try{pilhaA.printpilha();}
        catch (Erro_na_pilha &E){E.print_erro();}
        break;
      }
    default:{cout<<"Opcao invalida!!!"<<endl<<endl;}
    }  
    }

};

O próximo exemplo é praticamente igual aos anteriores. O que o distingue é o facto de não fazer o tratamento de erro. Agora podem ver as diferenças na execução. Outra diferença é que agora vou usar vectores e no anterior usei memória dinâmica ...

Pilhas.cpp:

#include <iostream>
#include "Ponto.cpp"

using namespace std;

template <class C, const int maximo>


class Pilha
{
private:
  struct no_pilha
  {
    C* elem;
    no_pilha* ponta;
  };
  int n_elem;
  no_pilha* topo;
public:
  Pilha(){topo=NULL;n_elem=0;}

  virtual int get_maximo()const{return maximo;}


  virtual int get_n_elem()const{return n_elem;}

  virtual void push(C &i)
  {
    if (n_elem<maximo)
      {
    no_pilha* novo=new no_pilha;
    novo->elem=&i;
    novo->ponta=topo;
    topo=novo;
    n_elem++;
      }
  }

  virtual C* pop()
  {
    if (topo!=NULL)
      {
    no_pilha* aux=new no_pilha;
    aux=topo;
    topo=topo->ponta;
    C* removido=(aux->elem);
    delete aux;
    n_elem--;
    return removido;
      }
  }

  virtual void printpilha()const
  {
    if (topo!=NULL)
    {
       no_pilha* aux= new no_pilha;
       aux=topo;
       int contador=n_elem;
       cout <<endl<<"________Os elementos da Pilha :_______ "<<endl<<endl;
       while (aux!=NULL)
       {
         cout<<contador<<") ";
         contador--;
         aux->elem->print();
         aux=(aux->ponta);
         cout<<"\n";
       }
      cout<<"\n";
    }
    else
      cout<<"________A pilha esta vazia.________ "<<endl<<endl;
  }

};


int main()
{
  Pilha<Par,10> pilhaA;
  int opcao=1;
  cout<<endl;
  cout<<endl;
  Par Pr[10];
  Ponto Pt[10];
  while (opcao!=0)
    { cout<<"\t################################"<<endl;
      cout<<"\t# Escolha a opção:             #"<<endl;
      cout<<"\t# 1) Adicionar Par da pilha.   #"<<endl;
      cout<<"\t# 2) Adicionar Ponto da pilha. #"<<endl;
      cout<<"\t# 3) Remover elemento do topo. #"<<endl;
      cout<<"\t# 4) Listar elementos da pilha.#"<<endl;
      cout<<"\t# 0) Sair.                     #"<<endl;
      cout<<"\t################################"<<endl;
      cout<<endl;
      cout<<endl;
      cin>>opcao;
      switch (opcao)
    {
    case 0:
      { cout<<"Adeus..."<<endl<<endl;
        break;
      }
    case 1:
      {
        if (pilhaA.get_n_elem()<pilhaA.get_maximo())
          {
        cout<<"Coordenadas do tipo Par:"<<endl<<"->";
        double a;
        double b;
        cin>> a;
        cout<<"->";
        cin>> b;
        Pr[(pilhaA.get_n_elem())].set_left(a);
        Pr[(pilhaA.get_n_elem())].set_right(b);
        pilhaA.push(Pr[(pilhaA.get_n_elem())]);
          }
        else
          cout<<"______A pilha cheia.________"<<endl<<endl;
        break;
      }
    case 2:
      {
        if (pilhaA.get_n_elem()<pilhaA.get_maximo())
          {
        cout<<"Coordenadas do tipo Ponto:"<<endl<<"->";
        double x;
        double y;
        cin>> x;
        cout<<"=>";
        cin>> y;
        Pt[(pilhaA.get_n_elem())].set_left(x);
        Pt[(pilhaA.get_n_elem())].set_right(y);
        pilhaA.push(Pt[(pilhaA.get_n_elem())]);
          }
        else
          cout<<"_____________A pilha esta cheia.___________"<<endl<<endl;
        break;
      }
    case 3:
      {
        if (pilhaA.get_n_elem()>0)
          {
        cout<<"O elemento da pilha :";pilhaA.pop()->print();cout<<" foi removido da pilha."<<endl<<endl;
          }
        else
          cout<<"_________________A pilha esta vazia.__________"<<endl<<endl;
        break;
      }
    case 4:
      {
        pilhaA.printpilha();
        break;
      }
    default:{cout<<"Opcao invalida!!!"<<endl<<endl;}
    }  
    }

};