Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211

    C++ metodo natural merge sort

    ho implementato la classe lista come clsse base e la classe lista con puntatori come classe derivata. nel test della classe, precisamente per quanto riguarda il metodo natural merge sort, ho un problema. posto le classi.

    nodop.h
    codice:
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    template<class tipoelem>
    class nodop
    {
       public:
          nodop();
          void setprec(nodop *);
          void setelem(tipoelem);
          void setsuc(nodop *);
          nodop *getprec();
          tipoelem getelem();
          nodop *getsuc();
       private:
          nodop *precedente;
          tipoelem elemento;
          nodop *successivo;
    };
    
    template<class tipoelem>
    nodop<tipoelem>::nodop()
    {
       precedente = NULL;
       elemento = 0;
       successivo = NULL;
    }
    
    template<class tipoelem>
    void nodop<tipoelem>::setprec(nodop<tipoelem> *prec)
    {
       precedente = prec;
    }
    
    template<class tipoelem>
    void nodop<tipoelem>::setelem(tipoelem elem)
    {
       elemento = elem;
    }
    
    template<class tipoelem>
    void nodop<tipoelem>::setsuc(nodop<tipoelem> *succ)
    {
       successivo = succ;
    }
    
    template<class tipoelem>
    nodop<tipoelem> *nodop<tipoelem>::getprec()
    {
       return(precedente);
    }
    
    template<class tipoelem>
    tipoelem nodop<tipoelem>::getelem()
    {
       return(elemento);
    }
    
    template<class tipoelem>
    nodop<tipoelem> *nodop<tipoelem>::getsuc()
    {
       return(successivo);
    }
    lista.h
    codice:
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    template<class posizione, class tipoelem>
    class lista
    {
       public:
          virtual void crealista() = 0;
          virtual bool listavuota() = 0;
          virtual posizione primolista() = 0;
          virtual bool finelista(posizione) = 0;
          virtual posizione succlista(posizione) = 0;
          virtual posizione predlista(posizione) = 0;
          virtual tipoelem leggilista(posizione) = 0;
          virtual void scrivilista(posizione, tipoelem) = 0;
          virtual void inslista(posizione, tipoelem) = 0;
          virtual void canclista(posizione) = 0;
          
          void stampalista();
          void fondiordinate(lista &, lista &;
          void epurazione();
          void naturalmergesort();
       private:
          void distribuisci(lista, lista);
          void copiacatena(posizione &, lista, posizione &, lista &;
          void copia(posizione &, lista, posizione &, lista &, bool &;
          void merge(lista, lista, lista &, int &;
          void findicatena(posizione &, lista, posizione &, lista, posizione &, lista &;
          
    };
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::stampalista()
    {
       posizione p = primolista();
       while(!finelista(p))
       {
          cout << leggilista(p) << "\n";
          p = succlista(p);
       }
       cout << "\n";
    }
       
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::fondiordinate(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B)
    {
       posizione pa = A.primolista();
       posizione pb = B.primolista();
       posizione pc = primolista();
       
       tipoelem elem1 = A.leggilista(pa);
       tipoelem elem2 = B.leggilista(pb);
       while(!A.finelista(pa) && !B.finelista(pb))
       {
          if(elem1 <= elem2)
          {
             inslista(pc, elem1);
             pa = A.succlista(pa);
          }
          else
          {
             inslista(pc, elem2);
             pb = B.succlista(pb);
          }
          elem1 = A.leggilista(pa);
          elem2 = B.leggilista(pb);
       }
       while(!A.finelista(pa))
       {
          inslista(pc, elem1);
          pa = A.succlista(pa);
          elem1 = A.leggilista(pa);
       }
       while(!B.finelista(pb))
       {
          inslista(pc, elem2);
          pb = B.succlista(pb);
          elem2 = B.leggilista(pb);
       }
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::epurazione()
    {
       posizione p = primolista();
       posizione q;
       posizione t;
       while(!finelista(p))
       {
          q = succlista(p);
          while(!finelista(q))
          {
             if(leggilista(p) == leggilista(q))
             {
                t = succlista(q);
                canclista(q);
                q = t;
             }
             else
                q = succlista(q);
          }
          p = succlista(p);
       }
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::naturalmergesort()
    {
       int numerocatene;
       lista<posizione, tipoelem> A, B, L;
       do
       {
          A.crealista();
          B.crealista();
          distribuisci(A, B);
          numerocatene = 0;
          crealista();
          merge(A, B, &L, &numerocatene);
       }while(numerocatene != 1);
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::distribuisci(lista<posizione, tipoelem> A, lista<posizione, tipoelem> B)
    {
       posizione p = primolista();
       posizione pa = A.primolista();
       posizione pb = B.primolista();
       do
       {
          copiacatena(&p, this, &pa, &A);
          if(!finelista(p))
             copiacatena(&p, this, &pb, &B);
       }while(!finelista(p));
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::copiacatena(posizione &p, lista<posizione, tipoelem> L, posizione &pa, lista<posizione, tipoelem> &A)
    {
       bool finecatena = false;
       do
          copia(&p, this, &pa, &A, &finecatena);
       while(!finecatena);
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::copia(posizione &p, lista<posizione, tipoelem> L, posizione &pa, lista<posizione, tipoelem> &A, bool &finecatena)
    {
       tipoelem elemento = leggilista(p);
       A.inslista(pa, elemento);
       p = succlista(p);
       pa = succlista(pa);
       if(finelista(p))
          finecatena = true;
       else
          finecatena = (elemento > leggilista(p));
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::merge(lista<posizione, tipoelem> A, lista<posizione, tipoelem> B, lista<posizione, tipoelem> &L, int &numcatene)
    {
       posizione p = primolista();
       posizione pa = A.primolista();
       posizione pb = B.primolista();
       
       while(!A.finelista(pa) && !B.finelista(pb))
       {
          fondicatena(&pa, A, &pb, B, &p, &L);
          numcatene++;
       }
       while(!A.finelista(pa))
       {
          copiacatena(&pa, A, &p, &L);
          numcatene++;
       }
       while(!B.finelista(pb))
       {
          copiacatena(&pb, B, &p, &L);
          numcatene++;
       }
    }
    listap.h
    codice:
    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include "lista.h"
    #include "nodop.h"
    
    using namespace std;
    
    template<class tipoelem>
    class listap : public lista<nodop<tipoelem> *, tipoelem>
    {
       public:
          typedef nodop<tipoelem> *posizione;
          listap();                             //costruttore di default
          void crealista();                     //crea la lista vuota
          bool listavuota();                    //stabilisce se la lista è vuota o meno
          posizione primolista();               //restituisce la posizione del primo elemento della lista
          bool finelista(posizione);            //stabilisce se il nodo è l'ultimo della lista
          tipoelem leggilista(posizione);       //restituisce l'elemento della posizione specificata
          posizione succlista(posizione);       //restituisce la posizione del nodo successivo 
          posizione predlista(posizione);       //restituisce la posizione del nodo precedente
          void scrivilista(posizione, tipoelem);//scrive l'elemtno nel nodo specificato dalla posizione
          void inslista(posizione, tipoelem); //inserisce un nodo e scrive l'elemento nella posizione specificata 
          void canclista(posizione);          //elimina il nodo nella posizione specificata
       private:
          nodop<tipoelem> cella;                 //nodo della lista (nodo sentinella)
    };
    
    template<class tipoelem>
    listap<tipoelem>::listap()
    {
       crealista();                             //il costruttore invoca il metodo crealista
    }
    
    template<class tipoelem>
    void listap<tipoelem>::crealista()
    {
       cella.setprec(&cella);
       cella.setsuc(&cella);
       cella.setelem(0);
    }
    
    template<class tipoelem>
    bool listap<tipoelem>::listavuota()
    {
       return((cella.getprec() == &cella) && (cella.getsuc() == &cella));
    }
    
    template<class tipoelem>
    typename listap<tipoelem>::posizione listap<tipoelem>::primolista()
    {
       return(cella.getsuc());
    }
    
    template<class tipoelem>
    bool listap<tipoelem>::finelista(typename listap<tipoelem>::posizione pos)
    {
       return(pos == &cella);
    }
    
    template<class tipoelem>
    tipoelem listap<tipoelem>::leggilista(typename listap<tipoelem>::posizione pos)
    {
       return(pos->getelem());
    }
    
    template<class tipoelem>
    void listap<tipoelem>::scrivilista(typename listap<tipoelem>::posizione pos, tipoelem elem)
    {
       pos->setelem(elem);
    }
    
    template<class tipoelem>
    typename listap<tipoelem>::posizione listap<tipoelem>::succlista(typename listap<tipoelem>::posizione pos)
    {
       return(pos->getsuc());
    }
    
    template<class tipoelem>
    typename listap<tipoelem>::posizione listap<tipoelem>::predlista(typename listap<tipoelem>::posizione pos)
    {
       return(pos->getprec());
    }
    
    template<class tipoelem>
    void listap<tipoelem>::inslista(typename listap<tipoelem>::posizione pos, tipoelem elem)
    {
       posizione temp = new nodop<tipoelem>;
       
       temp->setprec(pos->getprec());
       temp->setsuc(pos);
       (pos->getprec())->setsuc(temp);
       pos->setprec(temp);
       temp->setelem(elem);
       pos = temp;
    }
    
    template<class tipoelem>
    void listap<tipoelem>::canclista(typename listap<tipoelem>::posizione pos)
    {
       posizione temp = pos;
       (pos->getsuc())->setprec(pos->getprec());
       (pos->getprec())->setsuc(pos->getsuc());
       pos = pos->getsuc();
       delete temp;
    }
    testlistap.cpp
    codice:
    #include "listap.h"
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    int main()
    {
       listap<int> list, list2, list3, list4;
       listap<int>::posizione pos = list.primolista();
       listap<int>::posizione pos2 = list2.primolista();
       listap<int>::posizione pos4 = list4.primolista();
       int k;
       
       for(int i = 0; i < 10; i++)
       {
          list.inslista(pos, (100 - (i * 10)));
          pos = list.primolista();
       }
       
       for(int i = 0; i < 10; i++)
       {
          list2.inslista(pos2, (50 - (i * 5)));
          pos2 = list2.primolista();
       }
    
       list.stampalista();
       list2.stampalista();
       
       cout << "\n\n";
          
       list3.fondiordinate(list, list2);
       list3.stampalista();
       cout << "\n\n";
       list3.epurazione();
       list3.stampalista();
       
       cout << "\n\n";
       for(int i = 0; i < 10; i++)
       {
          cin >> k;
          list4.inslista(pos4, k);
          pos2 = list2.primolista();
       }
       list4.stampalista();
       list4.naturalmergesort();
       cout << "\n\n";
       list4.stampalista();
       
       system("pause");
       return 0;
    }
    il problema che mi viene visualizzato quando faccio il test della lista è il seguente:
    114 C:\Dev-Cpp\esercizi\Lista\lista.h cannot declare variable `A' to be of type `lista<nodop<int>*, int>'
    because the following virtual functions are abstract:

    e si riferisce ai metodi virtali dichiarati nella classe base.
    come posso risolvere questo problema???

    per oregon: l'errore si riferisce alla riga 114 del metodo natural merge sort nella classe base lista.h

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466

    Re: C++ metodo natural merge sort

    Originariamente inviato da pietrol83
    per oregon: l'errore si riferisce alla riga 114 del metodo natural merge sort nella classe base lista.h
    Scusa Pietro, o conto le righe o copio il programma creando un progetto e *spero* che il numero di linea sia lo stesso. Perché creare equivoci?

    Cosa ti cosa

    segnare in rosso

    la riga in questione ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    va bhe non c'è un numero di riga preciso! è il metodo che non accetta gli argomenti. in pratica, facendo riferimento all'errore che ho scritto nella domanda, il metodo che nn va bene è il natural merge sort che si trova nella classe lista.h

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Originariamente inviato da pietrol83
    va bhe non c'è un numero di riga preciso!
    Ma che dici?

    La linea che viene evidenziata è questa

    lista<posizione, tipoelem> A, B, L;

    cosa che potevi fare anche tu per far risparmiare tempo a chi vuole risponderti.

    E vuol dire semplicemente che non puoi istanziare un oggetto A (B o L) perché la classe lista ha una o più funzioni virtuali pure.

    P.S. In futuro indica la riga come ho fatto io perché non sempre avrò tempo, almeno personalmente, di farlo e questo mi impedirà di risponderti.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    ok, ti chiedo scusa per il disturbo. come potrei fare per mantenere il metodo natural merge sort nella classe base?

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    ciao oregon, ho provato a fare il natural merge sort passando le liste tramite puntatori, però nel metodo copia mi da un problema che non riesco a risolvere: ti posto solo la classe lista.h perchè le altre classi sono sempre le stesse.

    lista.h
    codice:
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    template<class posizione, class tipoelem>
    class lista
    {
       public:
          virtual void crealista() = 0;
          virtual bool listavuota() = 0;
          virtual posizione primolista() = 0;
          virtual bool finelista(posizione) = 0;
          virtual posizione succlista(posizione) = 0;
          virtual posizione predlista(posizione) = 0;
          virtual tipoelem leggilista(posizione) = 0;
          virtual void scrivilista(posizione, tipoelem) = 0;
          virtual void inslista(posizione, tipoelem) = 0;
          virtual void canclista(posizione) = 0;
          
          void stampalista();
          void fondiordinate(lista &, lista &);
          void epurazione();
          void naturalmergesort();
       private:
          void distribuisci(lista *, lista *);
          void copiacatena(posizione *, lista *, posizione *, lista *);
          void copia(posizione *, lista *, posizione *, lista *, bool *);
          void merge(lista *, lista *, lista *, int *);
          void fondicatena(posizione *, lista *, posizione *, lista *, posizione *, lista *);
          
    };
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::stampalista()
    {
       posizione p = primolista();
       while(!finelista(p))
       {
          cout << leggilista(p) << "\n";
          p = succlista(p);
       }
       cout << "\n";
    }
       
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::fondiordinate(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B)
    {
       posizione pa = A.primolista();
       posizione pb = B.primolista();
       posizione pc = primolista();
       
       tipoelem elem1 = A.leggilista(pa);
       tipoelem elem2 = B.leggilista(pb);
       while(!A.finelista(pa) && !B.finelista(pb))
       {
          if(elem1 <= elem2)
          {
             inslista(pc, elem1);
             pa = A.succlista(pa);
          }
          else
          {
             inslista(pc, elem2);
             pb = B.succlista(pb);
          }
          elem1 = A.leggilista(pa);
          elem2 = B.leggilista(pb);
       }
       while(!A.finelista(pa))
       {
          inslista(pc, elem1);
          pa = A.succlista(pa);
          elem1 = A.leggilista(pa);
       }
       while(!B.finelista(pb))
       {
          inslista(pc, elem2);
          pb = B.succlista(pb);
          elem2 = B.leggilista(pb);
       }
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::epurazione()
    {
       posizione p = primolista();
       posizione q;
       posizione t;
       while(!finelista(p))
       {
          q = succlista(p);
          while(!finelista(q))
          {
             if(leggilista(p) == leggilista(q))
             {
                t = succlista(q);
                canclista(q);
                q = t;
             }
             else
                q = succlista(q);
          }
          p = succlista(p);
       }
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::naturalmergesort()
    {
       int numerocatene;
       lista<posizione, tipoelem> *A, *B, *L;
       do
       {
          A->crealista();
          B->crealista();
          distribuisci(A, B);
          numerocatene = 0;
          crealista();
          merge(A, B, L, &numerocatene);
       }while(numerocatene != 1);
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::distribuisci(lista<posizione, tipoelem> *A, lista<posizione, tipoelem> *B)
    {
       posizione p = primolista();
       posizione pa = A->primolista();
       posizione pb = B->primolista();
       do
       {
          copiacatena(&p, this, &pa, A);
          if(!finelista(p))
             copiacatena(&p, this, &pb, B);
       }while(!finelista(p));
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::copiacatena(posizione *p, lista<posizione, tipoelem> *L, posizione *pa, lista<posizione, tipoelem> *A)
    {
       bool finecatena = false;
       do
       {
            copia(&p, L, &pa, A, &finecatena); 
             while(!finecatena);
    }
    h
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::copia(posizione *p, lista<posizione, tipoelem> *L, posizione *pa, lista<posizione, tipoelem> *A, bool *finecatena)
    {
       tipoelem elemento = leggilista(p);
       A->inslista(pa, elemento);
       p = succlista(p);
       pa = succlista(pa);
       if(finelista(p))
          finecatena = true;
       else
          finecatena = (elemento > leggilista(p));
    }
    
    template<class posizione, class tipoelem>
    void lista<posizione, tipoelem>::merge(lista<posizione, tipoelem> *A, lista<posizione, tipoelem> *B, lista<posizione, tipoelem> *L, int *numcatene)
    {
       posizione p = primolista();
       posizione pa = A->primolista();
       posizione pb = B->primolista();
       
       while(!A->finelista(pa) && !B->finelista(pb))
       {
          fondicatena(&pa, A, &pb, B, &p, L);
          numcatene++;
       }
       while(!A->finelista(pa))
       {
          copiacatena(&pa, A, &p, L);
          numcatene++;
       }
       while(!B->finelista(pb))
       {
          copiacatena(&pb, B, &p, L);
          numcatene++;
       }
    }
    in pratica il problema è il seguente:
    144 C:\Dev-Cpp\esercizi\Lista\lista.h no matching function for call to `lista<nodop<int>*, int>::copia(nodop<int>***, lista<nodop<int>*, int>*&, nodop<int>***, lista<nodop<int>*, int>*&, bool*)'

    secondo me la chiamata del metodo corrisponde con il prototipo però mi dà errore. come mai?

    PS: ho messo in rosso la riga dove mi dà l'errore.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.