klasy/tablice pochodne

0

Witam,
mam stworzyc system klas pozwalajacy stworzyc trochę "zmutowaną" rodzinkę, czyli: mamy osobę, możemy dodac jej ojca , 2 ojca , syna, 2 syna, 3 syna itd. przy czym np. 2 syn może miec rowniez 2 ojcow, którzy np. mogą miec tego samego ojca (liczba ojcow i synow nie powinna byc ograniczona). Nie mam już kompletnie pomysłu jak to zrobic, a termin się zbliża. Próbowałem to robic na tablicach wielowymiarowych, tablicach ojciec i syn oraz próbowałem się bawic w dziedziczenie, ale tutaj to już na samym początku nie potrafiłem sobie poradzic z problemem. Any idea? :(

0

Podaj po kolei te wszystkie ograniczenia. Na razie rozumiem, że osoba może mieć 1...N ojców i 1...N synów. Teraz podaj warunki, które nie mogą być spełnione

0

osoba1 osoba 2 Myślę, że obrazując obrazkiem bedzie lepiej. Można to porównac do przestrzeni nazw. Osoba6 znajudje się
| \ / \ w przestrzeni nazw osoba3, a osoba3 znajduje się w przestrzeni nazw osoba1. Osoba 4 jest w przestrzeni
| \ / \ nazw osoba1 i osoba2. Użytkownik ma podawac słowo i określac, gdzie ono w tym grafie będzie. Szerzej
| \ / \ mówiąc użytkownik ma to stworzyc takie coś ( w j. polskim to tezaurus :P). Bez opcji usuwania. Budujemy i
osoba3 osoba4 osoba5 wyświetlamy na ekranie. Mam nadzieję, że trochę rozjaśniłem mój problem. Dzięki za zainteresowanie :)
|
|
|
osoba6

0

Raczej zwykła relacja N-N. Czyli tablica ojców, tablica synów i tablica relacji między nimi.

0

dziękuje za odpowiedzi. w sumie to ma jeszcze potem wyrzucac na ekran powstałe drzewo. W sumie nie wiem, która metoda będzie do tego lepsza.. do rana spróbuje coś rozkminic z podanymi propozycjami. a nuż coś napiszę :P

0

Czemu wszyscy sa za tym, zeby stworzyc tablice a nie klasy?

0

Imo jeżeli to ma być system klas, to zbuduj to na drzewie. Chodzi o to, że każdy węzeł będzie mieć listę ojców i listę synów oraz metody do ich manipulacji. Pamiętaj, że drzewo ma korzeń, czyli co najmniej jednego ojca, który nie jest synem.

EDIT: Spojrzałem jeszcze raz na "rysunek". Widzę, że tutaj masz dwa korzenie, czyli są dwa drzewa,więc mówimy tu już o lesie ;].

Raczej zwykła relacja N-N. Czyli tablica ojców, tablica synów i tablica relacji między nimi.

Tzn. dwie tablice (plus trzecia relacyjna)? Z opisu wynika, że ojciec może być jednocześnie synem, więc będzie w dwóch tablicach?

0

Tego raczej nie można nazwać drzewem (ani lasem). W drzewie każdy element ma dokładnie jednego ojca. To po prostu graf (skierowany, bez cykli). Nie ma co tu na siłę wciskać zróżnicowanej hierarchii klas. Każdy element będzie jednorodny (każdy może mieć synów/ojców). Proponuję zwyczajnie:

struct Element {
   vector<Element*> synowie;

   DodajSyna(Element *syn) {

      /* ---> tu sprawdź, czy nie tworzysz cyklu (DFS) <--- */

      /* ---> sprawdź też, czy 'syn' jest praojcem
      /*        jeśli tak to usuń z tablicy praojców (zobacz klasę Graf)  <--- */

      synowie.push_back(syn);
   }
};

struct Graf : Element { // graf to wirtualny ojciec wszystkich pra-ojców (elementów bez ojca)
};

// EDIT
Aha, jeszcze co do cykli.
Czy para ojciec-syn może być jednocześnie parą syn-ociec? Jeśli tak, to sytuacja się zmieni. Cykle będą dozwolone, a pra-ojców może nie być wcale!

0

Witam, po dłuższej przerwie. Trochę rozmawiałem z wykładowcą na ten temat. Ma to byc rzeczywiście graf skierowany niespójny.
Budowa klasy ma byc taka:

 string nazwa
 lista wskaznikow na synow

bez używania klasy vector. Jaka to ma byc lista? enum, inicjalizacyjna? Przy okazji ma byc wczytywanie i zczytywanie do i z pliku.

edit: no i na samej górze ma byc tylko 1 osoba (praojciec). nie ma zamiennych par syn-ojciec, ojciec-syn

0
hard2say napisał(a)

bez używania klasy vector. Jaka to ma byc lista? enum, inicjalizacyjna?
Ha ha. No tak, pod słowem "lista" kryje się wiele haseł. Widać, że nie bardzo kumasz o co chodzi "w tym całym programowaniu" ;) Ma to być lista jako struktura danych. Jak nie vector to użyj klasy list. Dopiszesz do tego wykrywanie cykli, zapis/odczyt do pliku (wszystko z pomocą DFS) i będzie gotowe.

0

nie ukrywam, że nie jestem programistą :) i mimo tego, że jestem umysłem ścisłym nauka programowania idzie mi jak krew z nosa... dzięki za pomoc. projekt na jutro, więc może się wyrobie :P

0

Witam ponownie!
Zrobiłem dośc spory progres w projekcie, ale jest problem :) Program działa dobrze dopóki dodajemy synów i wchodzimy "wgłąb". Jeśli jednak iterator ma się cofnac, wyskakują wdzięczne krzaki. Wydaje mi się, że coś jest nie tak w metodzie createTezaurus (plik verbum.cc)

sedis - synonimy
filius - synowie
klasa verbum - klasa słowa
klasa tezaurus - klasa operująca na słowie

Oto program:

main.cc

#include <iostream>
using namespace std;
#include "verbum.h"
#include "tezaurus.h"
#include "verbum.cc"
#include "tezaurus.cc"


int main()
{

    verbum First = verbum("AVUS");
    First.createTezaurus();
}

verbum.h

#ifndef VERBUM_H
#define VERBUM_H
#include <iostream>
#include <list>
#include <string>

class verbum
{
    public:
    string nomen;
    list<verbum>filius;
    list<string>sedis;

    verbum(const string);
    void addSedis();
    void addFilius();
    void createTezaurus();

};


#endif
 

verbum.cc

#include <iostream>
#include <list>
#include <string>
#include "verbum.h"

using namespace std;

verbum::verbum(const string nomen_)
    {
        nomen = nomen_;
    }

void verbum::addFilius()
{
    verbum filius_ = verbum("");
    cout << "Podaj nazwe syna slowa "<< nomen <<" lub wpisz NULL aby zakonczyc.\n";
    while(cin >> filius_.nomen && filius_.nomen != "NULL")
    {
        filius.push_back(filius_);
    }
}

void verbum::addSedis()
{
    string sedis_;
    cout << "Podaj nazwe synonimu slowa "<< nomen <<" lub wpisz NULL aby zakonczyc.\n";
    while(cin >> sedis_ && sedis_ != "NULL")
    {
        sedis.push_back(sedis_);
    }
}

void verbum::createTezaurus()
{
    addSedis();
    addFilius();

   for( list<verbum>::iterator temp=filius.begin(); temp != filius.end(); )
   {
      if (temp -> nomen =="")
         break;
      else
         {
          ++temp;
          temp -> createTezaurus();
         }

   }
}
 

tezaurus.h

#ifndef TEZAURUS_H
#define TEZAURUS_H
#include <iostream>
#include <list>
#include <string>
#include "verbum.h"

class tezaurus
{
    list<verbum>general;

    tezaurus();
    void addVerbum(const verbum&);
    bool checkVerbum(const verbum&);

};

#endif

tezaurus.cc

#include <iostream>
#include <list>
#include <string>
#include "tezaurus.h"

using namespace std;

tezaurus::tezaurus(){}

void tezaurus::addVerbum(const verbum& verbum_)
{
    if (checkVerbum(verbum_) == false)
    {
    general.push_back(verbum_);
    }
}

bool tezaurus::checkVerbum(const verbum& verbum_)
{
    bool duplicate = false;
    list<verbum>::iterator iter;

    iter=general.begin();
    while(iter != general.end())
    {
        if (verbum_.nomen == iter -> nomen)
        {
            duplicate = true;
        }
        ++iter;
    }
    return duplicate;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1