Jump to content
Sign in to follow this  
Marino

[Resolvido] Grafos-Classe- Duvida

Recommended Posts

Marino

Pessoal, mais uma vez, neste caso o programa compila mas nao corre! dá erro, já revi isto umas qntas vezes e sempre sem sucesso!  :bye2:  :bye2:

Tenho que entregar isto hoje de tarde  :wallbash:

Alguma alma caridosa, que tente ver onde a porca torce o rabo.

Já agora isto é uma classe de grafos com dois argumentos, nos e arestas, para um grafo de n nos pode ter n^2 arestas.

Se para mim que fiz isto é dificil detectar os erros, entao para vocês ainda pior  :cheesygrin: mas tentem  :D

#include <iostream>
#include <string>
using namespace std;
//Excepcoes
class GrafoCheio{};
class ArestaDesconhecida{};
class NoDesconhecido{};
class ArestaExistente{};

template <class N,class A> class CGrafo {
         struct Aresta { A val; bool usada; } ;
         struct No { N val; Aresta *arestas ; } ;
         
         No *v_nos;    // vector de nos
         int tamanho;
         int nn;       //n de nos
         int na;       //n de arestas
         public:
                CGrafo (const int n=10);
                ~CGrafo();
                CGrafo &inserir_no(const N &dados);
                CGrafo &inserir_aresta(const N &inicio, const N &fim , const A & dados);
                CGrafo &eliminar_aresta(const N &inicio,const N &fim);
                CGrafo &eliminar_no(const N &dados);
                A &valor_aresta(const N &inicio, const N &fim);
                void imprimir (std::ostream &os) const;
                int n_arestas(void) const;
                int n_nos(void) const;
                int capacidade(void) const;
                int pesquisa(const N &no);
                
                
};


template <class N,class A>  CGrafo<N,A>::CGrafo(const int n)
{
         tamanho = n;
         v_nos= new No[tamanho];
         nn=0;
         na=0;
         for (int i=0; i<n; i++)
         {
             v_nos[i].arestas = new Aresta[n];
             for (int j=0; j<n;j++)
                 v_nos[i].arestas[j].usada=false;
         }
}

template <class N,class A>  CGrafo<N,A>::~CGrafo()
{
         delete [] v_nos;
       /*int i;    Será necessario?
for(i=0;i<capacidade();i++)
	delete [] v_nos[i].arestas;

for(i=0;i<capacidade();i++)
	delete [] v_nos;*/
       
       
}

template <class N,class A> int CGrafo<N,A>::n_arestas(void) const
{
         return na;
}

template <class N,class A> int CGrafo<N,A>::n_nos(void) const
{
         return nn;
}

template <class N,class A> int CGrafo<N,A>::capacidade(void) const
{
         return tamanho;
}

template <class N,class A> CGrafo<N,A> &CGrafo<N,A>::inserir_no(const N &dados)
{
      if(tamanho == n_nos()) throw(GrafoCheio());
      else
      {
      
         int aux=n_nos();
         nn++;
         v_nos[aux].val=dados;
        /* for(int i=0; i<=n_nos(); i++)
         {
                 v_nos[aux].arestas[i].usada=false;  //Para colocar false em todas as arestas do no
         } */
      }
}

//Funçao Pesquisa Nó
template <class N,class A> int CGrafo<N,A>::pesquisa(const N &no)
{
for(int i=0;i<n_nos();i++)
	if(v_nos[i].val==no) return i;

  else return -1;
}



template <class N,class A> CGrafo<N,A> &CGrafo<N,A>::inserir_aresta(const N &inicio,const N &fim, const A &dados)
{
         //Pesquisa
         int aux=pesquisa(inicio), auxfim=pesquisa(fim);
         /*for(int i=0;i<=n_nos();i++)
            if(v_nos[i].val==inicio) aux =i;*/
         
            if(aux==-1) throw (ArestaDesconhecida()); 
         
        /* for(int=0; i<=n_nos();i++)
                    if(v_nos[i].val==inicio) auxfim=i;   */     
         
         if(auxfim==-1) throw (ArestaDesconhecida());
         
         if(v_nos[aux].arestas[auxfim].usada==true) throw (ArestaExistente());
         //-------------------
         
         v_nos[aux].arestas[auxfim].val=dados;
         v_nos[aux].arestas[auxfim].usada=true;
         na++;
         return *this;
}

template <class N,class A> A &CGrafo<N,A>::valor_aresta(const N &inicio,const N &fim)
{
         int auxini=pesquisa(inicio), auxfim=pesquisa(fim);
         if(v_nos[auxini].arestas[auxfim].usada==false) throw(ArestaDesconhecida());
         

return v_nos[auxini].arestas[auxfim].val;
}
         

template <class N,class A> CGrafo<N,A> &CGrafo<N,A>::eliminar_aresta(const N &inicio,const N &fim)
{
         int auxini=pesquisa(inicio), auxfim=pesquisa(fim);
         if(v_nos[auxini].arestas[auxfim].usada==false) throw(ArestaDesconhecida());
         
         v_nos[auxini].arestas[auxfim].usada=false;
         //v_nos[auxini].arestas[auxfim].val=0;
         na--;
      
return *this;
}
                 
template <class N,class A> CGrafo<N,A> &CGrafo<N,A>::eliminar_no(const N &dados)
{
       int aux = pesquisa(dados);
       if (aux==-1) throw(NoDesconhecido());
       
       for(int i =0; i<tamanho; i++)
       {
               if(v_nos[aux].arestas[i].usadas==true)
               {
                v_nos[aux].arestas[i].usadas=false;
               na--;
               }
       }
       nn--;
       
       return *this;
       
}

template <class N,class A> void CGrafo<N,A>::imprimir(std::ostream &os) const
{
                 
         for(int inicio=0 ; inicio< n_nos() ; inicio++)
         {
         os << "( ";
             for(int final=0; final<= capacidade(); final++)
             {
                     if(v_nos[inicio].arestas[final].usada==true)
                     os << v_nos[inicio].val << " [ " << v_nos[final].val << " " << v_nos[inicio].arestas[final].val << " ] ";
             }
         os << " ) ";
         }
         
}
         
      
template <class N,class A> std::ostream &operator<<(std::ostream &out,const CGrafo<N,A> &g)
{
         g.imprimir(out);
         
return out;       
}

O ccp Teste:

#include <string>
#include <iostream>
#include "CGrafo.h"

using namespace std;

int
main()
{

  CGrafo<string,int> g(5);

  // Inserir nós

  g.inserir_no("A");
  g.inserir_no("B");
  g.inserir_no("C");
  g.inserir_no("D");
  g.inserir_no("E");

  // Erro
  //  g.inserir_no("F");

  // Erro
  // g.inserir_no("B");

    // Inserir arestas

  g.inserir_aresta("A", "B", 5);
  g.inserir_aresta("A", "C", 8);
  g.inserir_aresta("B", "D", 9);
  g.inserir_aresta("C", "D", 3);
  g.inserir_aresta("C", "E", 4);
  g.inserir_aresta("D", "E", 2);
  g.inserir_aresta("D", "B", 11);

  // Erro
  // g.inserir_aresta("D", "B", 12);

  //cout << "Grafo: " << g << '\n';
// Estatisticas
  cout << "Nº de nós: " << g.n_nos() << "...";
  if (g.n_nos() != 5)
    cout << "(Erro!)\n";
  else
    cout << "(OK)\n";

  cout << "Nº de arestas: " << g.n_arestas() << "...";
  if (g.n_arestas() != 7)
    cout << "(Erro!)\n";
  else
    cout << "(OK)\n";
    
  // Eliminar arestas

  g.eliminar_aresta("D", "E");
  cout << "Uma aresta a menos: " << g << '\n';
  
  bool failed = false;
  
  // Erro
  // g.eliminar_aresta("A", "D");

  // Mudar valores
  g.valor_aresta("A", "B") = 15;

  //cout << "Aresta A->B modificada: " << g << '\n';

  cout << "Novo valor: " << g.valor_aresta("A", "B") << "...";
  if (g.valor_aresta("A", "B") != 15)
    cout << "(Erro!)\n";
  else
    cout << "(OK)\n";

  cout << "**Fim**\n";
  
  system("PAUSE");
  return 0;
}

Share this post


Link to post
Share on other sites
brink@ero

Detectar erros que o compilador não detecta é difícil, principalmente para quem está fora do programa e os teus comentários no código são muito poucos.

Quando fazes o código tens de o comentar para que alguem do exterior perceba facilmente o teu código!!

Vou dar uma vista de olhos e tentar perceber o que tens.

EDIT:


1.º

Não percebo isto:

//Funçao Pesquisa Nó
template <class N,class A>
int CGrafo<N,A>::pesquisa(const N &no)
{
for(int i=0;i<n_nos();i++)
	if(v_nos[i].val==no)
		return i;
	else
		return -1;
}

Qual é a funcionalidade do for? Isto só corre uma vez!


2.º

Falta um return nesta função:

template <class N,class A>
CGrafo<N,A> &CGrafo<N,A>::inserir_no(const N &dados)
{
      if(tamanho == n_nos()) throw(GrafoCheio());
      else
      {
      
         int aux=n_nos();
         nn++;
         v_nos[aux].val=dados;
        /* for(int i=0; i<=n_nos(); i++)
         {
                 v_nos[aux].arestas[i].usada=false;  //Para colocar false em todas as arestas do no
         } */
      }
}


3.º

Estás a usar mal o throw!!!

1.º - O throw devolve algo para depois saberes qual foi o erro, neste caso estás a devolver uma classe que nem sequer foi inicializada. (não percebo porque estás a fazer isto)

2.º - Se estas a usar o throw, estas a provocar um erro no teu programa para depois tirares aproveito disso. Mas não estás a fazer nada! Tens de inserir Try... Catch(...) ... para teres proveito do uso do throw.

Deixo aqui um exemplo  no teu código e altera o resto de modo a que isso funcione:

template <class N,class A> CGrafo<N,A> &CGrafo<N,A>::inserir_aresta(const N &inicio,const N &fim, const A &dados)
{
         //Pesquisa
         int aux=pesquisa(inicio), auxfim=pesquisa(fim);
         /*for(int i=0;i<=n_nos();i++)
            if(v_nos[i].val==inicio) aux =i;*/
         
            if(aux==-1) throw ("ArestaDesconhecida");//ArestaDesconhecida); 
         
        /* for(int=0; i<=n_nos();i++)
                    if(v_nos[i].val==inicio) auxfim=i;   */     
         
         if(auxfim==-1) throw ("ArestaDesconhecida");//ArestaDesconhecida());
         
         if(v_nos[aux].arestas[auxfim].usada==true) throw ("ArestaExistente");//ArestaExistente());
         //-------------------
         
         v_nos[aux].arestas[auxfim].val=dados;
         v_nos[aux].arestas[auxfim].usada=true;
         na++;
         return *this;
}

try
{

  g.inserir_aresta("A", "B", 5);
  g.inserir_aresta("A", "C", 8);
  g.inserir_aresta("B", "D", 9);
  g.inserir_aresta("C", "D", 3);
  g.inserir_aresta("C", "E", 4);
  g.inserir_aresta("D", "E", 2);
  g.inserir_aresta("D", "B", 11);
}
catch(char *s)
{
 printf("deu erro aqui: %s\n",s);
 system("pause");
 ExitProcess(-1);
}

Espero que percebas. O que o throw manda é apanhado pelo Catch(...) e ai fazes o que quiseres! Podes ter também vários catch para diferentes argumentos.

Share this post


Link to post
Share on other sites
Marino

Obrigado! tens dado imensa ajuda. Agora que se vai progredindo, olha-se para trás e vê-se os erros infantis que cometi  :D

Por exemplo aquilo do throw  😳

Agora já estou a dar STL, já fiquei a saber o que era o #include <vector>  🤔

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.