• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Marino

[Resolvido] Grafos-Classe- Duvida

4 mensagens neste tópico

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  :biggrin: 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;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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>  :hmm:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora