Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211

    C++ struttura dati insieme con vettore booleano

    ciao a tutti,
    ho creato una struttura dai insieme con un vettore booleano e a me sembra essere fatto bene. ho notato che quando testo i metodi ottengo dei risulatati non attesi. sto cercando di capire dove sia il problema ma non ne vengo a capo. io penso sia il compilòatore che mi ha voltato le spalle. potete dare voi un'occhiata e dirmi dov'è il problema (qualora ce ne fosse uno)?
    posto i codici:

    insiemev.h
    codice:
    #ifndef insiemev_h
    #define insiemev_h
    
    #include "insieme.h"
    #include<iostream>
    #include<stdlib.h>
    
    using namespace std;
    
    template<class tipoelem>
    class insiemev : public insieme<tipoelem>
    {
       public:
          insiemev(int);
          
          int card;
          
          void creainsieme();
          bool insiemevuoto();
          bool appartiene(tipoelem);
          void inserisci(tipoelem);
          void cancella(tipoelem);
          void unione(insiemev<tipoelem> &, insiemev<tipoelem> &);
          void intersezione(insiemev<tipoelem> &, insiemev<tipoelem> &);
          void differenza(insiemev<tipoelem> &, insiemev<tipoelem> &);
       
          void visualizzains();
       private:
          bool *set;
          int dimset;
    };
    
    #endif
    
    template<class tipoelem>
    void insiemev<tipoelem>::visualizzains()
    {
       for(int i = 0; i < dimset; i++)
       {
          if(this->appartiene(i))
          {
             cout << i << "  ";
          }
       }
       cout << "\n\n";
    }
    
    template<class tipoelem>
    insiemev<tipoelem>::insiemev(int dim)
    {
       dimset = dim;
       this->creainsieme();
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::creainsieme()
    {
       set = new bool[dimset];
       for(int i = 0; i < dimset; i++)
          set[i] = false;
       card = 0;
    }
    
    template<class tipoelem>
    bool insiemev<tipoelem>::insiemevuoto()
    {
       return(card == 0);
    }
    
    template<class tipoelem>
    bool insiemev<tipoelem>::appartiene(tipoelem elem)
    {
       return(set[elem]);
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::inserisci(tipoelem elem)
    {
       if(!this->appartiene(elem))
       {
          set[elem] = true;
          ++card;
       }
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::cancella(tipoelem elem)
    {
       if(set[elem])
       {
          set[elem] = false;
          card--;
       }
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::unione(insiemev<tipoelem> &A, insiemev<tipoelem> &B)
    {
       for(int i = 0; i < dimset; i++)
       {
          if(A.appartiene(i) || B.appartiene(i))
             this->inserisci(i);
       }
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::intersezione(insiemev<tipoelem> &A, insiemev<tipoelem> &B)
    {
       for(int i = 0; i < card; i++)
       {
          if(A.appartiene(i) && B.appartiene(i))
             this->inserisci(i);
       }
    }
    
    template<class tipoelem>
    void insiemev<tipoelem>::differenza(insiemev<tipoelem> &A, insiemev<tipoelem> &B)
    {
       for(int i = 0; i < card; i++)
       {
          if(A.appartiene(i) && !B.appartiene(i))
             this->inserisci(i);
       }
    }
    testinsieme.cpp
    codice:
    #include "insiemev.h"
    #include<iostream>
    #include<stdlib.h>
    
    using namespace std;
    
    int main()
    {
       cout << "                ***test insieme con vettore***\n\n";
       int dim = 10;                  
       insiemev<int> ins(dim);
       ins.inserisci(1);
       ins.inserisci(2);     
       ins.visualizzains();
       int dim2 = 5;
       insiemev<int> ins2(dim2);
       ins2.inserisci(4);
       ins2.inserisci(2);
       ins2.visualizzains();
       int card3 = dim + dim2;
       insiemev<int> ins3(card3);
       ins3.unione(ins, ins2);
       ins3.visualizzains();
       
       system("pause");
       return 0;
    }
    il problema è: quando testo il metodo unione dovrei ottenere come risultato l'insieme conelementi {1, 2, 4} mentre mi viene visualizzato {1, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14}

    cosa ho fatto di sbagliato? vi prego aiutatemi.

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    E insieme.h ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    va bhe insieme.h contiene i metodi virtuali (che sono implementati in insiemev.h) e un metodo che non fa altro che chiamare i metodi per testarli.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ti dispiace mostrarlo?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    insieme.h
    codice:
    #ifndef insieme_h
    #define insieme_h
    
    #include<iostream>
    #include<stdlib.h>
    
    using namespace std;
    
    template<class tipoelem>
    class insieme
    {
       public:
          virtual void creainsieme() = 0;
          virtual bool insiemevuoto() = 0;
          virtual bool appartiene(tipoelem) = 0;
          virtual void inserisci(tipoelem) = 0;
          virtual void cancella(tipoelem) = 0;
          //virtual void unione(insieme<tipoelem> *, insieme<tipoelem> *) = 0;
          //virtual void intersezione(insieme<tipoelem> *, insieme<tipoelem> *) = 0;
          //virtual void differenza(insieme<tipoelem> *, insieme<tipoelem> *) = 0;
          
          void test();
    };
    
    #endif
    
    template<class tipoelem>
    void insieme<tipoelem>::test()
    {
       cout << "                  ***test del metodo CREAINSIEME***\n\n";
       cout << "il metodo CREAINSIEME crea un insieme privo di elementi. per provare il metodo\n";
       cout << "basta utilizzare il metodo INSIEMEVUOTO.\n\n";
       cout << "   insiemevuoto() = " << this->insiemevuoto() << "\n\n";
       system("pause");
       system("cls");
       
       cout << "                  ***test del metodo INSIEMEVUOTO***\n\n";
       cout << "il metodo INSIEMEVUOTO testa se l'insieme e' privo o meno di elementi.\n\n";
       cout << "   test del metodo su insieme privo di elementi:\n";
       cout << "      insiemevuoto() = " << this->insiemevuoto() << "\n";
       cout << "   test del metodo su insieme con almeno un elemento:\n";
       cout << "      inserimento di un valore nell'insieme: a = ";
       tipoelem a;
       cin >> a;
       this->inserisci(a);
       cout << "      insiemevuoto() = " << this->insiemevuoto() << "\n\n";
       system("pause");
       system("cls");
       
       cout << "                  ***test del metodo APPARTIENE***\n\n";
       cout << "il metodo APPARTIENE testa se il valore fornito come argomento e' presente\n";
       cout << "o meno tra i valori dell'insieme.\n\n";
       cout << "   test con esito positivo:\n";
       cout << "      appartiene(a) = " << this->appartiene(a) << "\n";
       cout << "   test con esito negativo:\n";
       cout << "      b = ";
       tipoelem b;
       cin >> b;
       cout << "      appartiene(b) = " << this->appartiene(b) << "\n\n";
       system("pause");
       system("cls");
       
       cout << "i metodi UNIONE, INTERSEZIONE e DIFFERENZA non vengono testati in quanto\n";
       cout << "essendo questa una class virtuale, non è possibile instanziare oggetti\n";
       cout << "insieme, ma bisognerebbe fornire i puntatori a insieme da un main.\n\n";
       system("pause");
    }
    questa è la classe base (virtuale)

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ma in

    unione

    nel for

    for(int i = 0; i < dimset; i++)

    tu controlli degli elementi che non esistono in A e/o B ...

    dimset infatti è maggiore della dimensione massima dei due insiemi e quindi sfori i rispettivi vettori
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Non controlli se si esce o no dai limiti dell' array di booleani:
    codice:
    template<class tipoelem>
    void insiemev<tipoelem>::unione(insiemev<tipoelem> &A, insiemev<tipoelem> &B)
    {
       int max=A.dimset;
       if(max<B.dimset)
           max=B.dimset;
       for(int i = 0; i < max; i++)
       {
          if(i<A.dimset)
             if(A.appartiene(i))
                this->inserisci(i);
          if(i<B.dimset)
             if(B.appartiene(i))
                this->inserisci(i);
       }
    }
    E non ti ha dato segmentation fault per caso.Per cui se l' array di booleani di B era composto da 5 campi, ha letto anche quelli oltre.E per caso ce ne erano alcuni che sono stati letti come veri.
    Ma potevi semplicemente risolvere con un:
    codice:
    template<class tipoelem>
    bool insiemev<tipoelem>::appartiene(tipoelem elem)
    {
       bool result=elem<dimset;
       if(result)
          result=set[elem];
       return result;
    }
    Però c'è da dire che al posto del metodo unione avresti potuto implementare l' operatore | , e che avendo realizzato questa classe con i template, ti da errore se tipoelem=string, visto che un valore come "ciao" non è un indice valido dell' array set.

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Aggiungo che, al di là del problema specifico, mi accorgo che non fai quasi mai un po' di degugging ...

    Se solo avessi eseguito il codice linea per linea, avresti scoperto subito il problema (a parte che avresti dovuto evitarlo in sede di progettazione).

    Insomma, quello che devi imparare a fare è un po' di debugging delle tue applicazioni.
    Perché scrivere del codice (sbagliato) è semplice ... correggerlo è molto più difficile (e non bisogna sempre e comunque affidarsi ad un forum ...)
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    [QUOTE]Originariamente inviato da ramy89

    codice:
       int max=A.dimset;
       if(max<B.dimset)
           max=B.dimset;
    se faccio in questo modo comunque sforo uno dei due array in quanto di dimensione minore rispetto all'altro.
    inoltre ho provato a fare come dici tu ma il risultato non è quello atteso.
    ho fatto una modifica ed ho ottenuto il risultato atteso. in pratica ho fatto due cicli, uno per A e uno per B:

    max = A.dimset;
    for(int i = 0; i < max; i++)
    {
    if(A.appartiene(i))
    this->inserisci(i);
    }

    e allo stesso modo per B

  10. #10
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    Originariamente inviato da oregon
    Aggiungo che, al di là del problema specifico, mi accorgo che non fai quasi mai un po' di degugging ...

    Se solo avessi eseguito il codice linea per linea, avresti scoperto subito il problema (a parte che avresti dovuto evitarlo in sede di progettazione).

    Insomma, quello che devi imparare a fare è un po' di debugging delle tue applicazioni.
    Perché scrivere del codice (sbagliato) è semplice ... correggerlo è molto più difficile (e non bisogna sempre e comunque affidarsi ad un forum ...)
    oregon hai perfettamente ragione, io non è che non faccio quasi mai il debugging; non lo faccio proprio, perchè avendo fatto tutto da solo senza seguire un corso o avendo qualcuno che mi insegnasse le cose, non ho nemmeno preso in considerazione il fatto del debugging.

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.