c++ dynamische Strukturen
-
Hallo,
ich habe gerade folgendes Problem:
Ich muss eine dynamische Datenstruktur entwerfen mit folgenden Bedingungen:->Der Benutzer muss eine unbestimmte Anzahl von Gruppen anlegen können.
->Jede Gruppe besitzt einen Gruppennamen, sowie eine Adresse.
->In jeder Gruppe muss der Benutzer eine unbestimmte Anzahl von Personen
anlegen können.
->Jede Person besitzt einen Namen und ein Passwort.Die unbestimmte Anzahl von Gruppen habe ich mit einer verketteten Liste
realisiert. Jetzt habe ich aber das Problem, dass es in jeder Gruppe noch
eine unbestimmte Anzahl von Personen gibt.
Brauche ich dafür jetzt eine verkettete Liste in einer verketteten Liste?
Vielleicht doch eher eine Baumstruktur??
Zu welcher Struktur würdet ihr mir raten?
Wer kennt sich aus und kann mir helfen?Vielen Dank und liebe Grüße.
Melli
-
Ich vermute, die verkettete Liste ahst du selbst geschrieben. Ist das zwingend vorgeschrieben? (Klingt ganz nach einer Schul-/Haus-/Uni-Aufgabe)
Angenommen, du hast eine Klasse "Gruppe". Dann wäre std::vector<Gruppe> normalerweise das ideale Konstrukt für dich.
Für die "Person" gilt dasselbe: Wenn du eine Klasse "Person" hast, dann ist std::vector<Person> das Mittel der Wahl für eine Liste von Personen.
Die Aufgabe, std::vector<Person> in die Klasse "Gruppe" zu integrieren, überlasse ich dir
Wenn du Schwierigkeiten hast, melde dich nochmal.Zur generellen Struktur: du hast eine Liste von "Gruppe". Jede Gruppe hat eine Liste von "Person". Die beiden Listen sind dabei völlig unabhängig voneinander, also für die Liste von "Gruppen" ist es völlig unerheblich, was genau sich in der Klasse "Gruppe" verbirgt.
Wenn du weiterhin Probleme hast, solltest du deinen Code posten. Falls dieser sehr lang sein sollte, kürze bitte soviel, wie möglich.
viele Grüße
Felix
-
Hey, vielen Dank für deine Antwort.
Du hast Recht, es ist für die Uni.
Die verkettete Liste für Gruppen habe ich selber geschrieben. Ich weiß jetzt nur nicht, wie ich weiter vorgehen soll. Nochmal eine verkettete Liste von Personen machen und dann versuchen die beiden ineinander zu wursteln? :((
Ehrlich gesagt habe ich noch nie mit <vector> gearbeitet. Gibt es also eine Möglichkeit um die verketteten Listen herumzukommen??
Bist wirklich mein Retter.Liebe Grüße.
Melli
-
Hallo Melli,
wenn du std::vector verwenden darfst, dann mache das unbedingt! Mit verketteten Listen handelst du dir über kurz oder lang nur Ärger ein. Das funktioniert dann prinzipiell so:
Gruppe gruppe1; Gruppe gruppe2; std::vector<Gruppe> gruppen; gruppen.push_back(gruppe1); gruppen.push_back(gruppe2);Google am besten mal nach "std::vector Tutorial" (oder sowas), dann solltest du damit recht schnell klarkommen.
Kennst du dich generell schon ein wenig mit objektorientierter Programierung aus? Oder wurdest du quasi heute Morgen ins kalte Wasser geschmissen?
viele Grüße
Felix
-
Ich glaub Felix meint das so in der Art.
#include <iostream> #include <vector> using namespace std; class PersonenListe { public: string GetName(); PersonenListe :: PersonenListe(string n); private: string Name; }; vector<PersonenListe>Personen; PersonenListe :: PersonenListe(string n) : Name(n) { } void InitialisierePersonenListeName( string n ) { Personen.push_back( PersonenListe(n) ); // Die Daten (string n) werden mithilfe des Konstruktors PersonenListe :: PersonenListe(string n); // in den Vector Personen gepusht } string PersonenListe :: GetName() { return Name; } int main() { InitialisierePersonenListeName("bob"); InitialisierePersonenListeName("john"); cout << Personen[0].GetName() << endl; cout << Personen[1].GetName() << endl; return 0; }Vector Referenz mit Beispielcode: http://www.cplusplus.com/reference/stl/vector/
-
Erst einmal vielen herzlichen Dank Felix.
Ich lese mir gerade die STL Containerfunktionen durch.
Es wäre wirklich super, wenn es so einfach gehen würde.
Du hast mir von vector<> geschrieben, beim überfliegen
bin ich gerade auch auf list<> gestoßen. Wird ne Weile
dauern, bis ich mich da eingelesen habe.
Heute werd ich erst einmal versuchen das umzusetzen,
was du mir geschrieben hast.
Und ja, ich habe schon ein wenig Erfahrung. Was man halt
in der Uni so macht...:/
Bleibt dann nur noch das Problem, wie ich eine list<Personen>
in eine list<gruppen> bringe
viele lieben Grüße.
Melli
-
das ist ziemlich genau das, was mir vorschwebte. Nur wollt ich Melli den Code nicht direkt so vorsetzen... bei selbst schreiben/nachlesen ist der Lerneffekt viel höher.
Und ja, es ist ein großer Unterschied, ob man ein fertiges Programm nachvollziehen kann oder ob man versucht, es selbst zu schreiben.
edit:
Melanie_27 schrieb:
Du hast mir von vector<> geschrieben, beim überfliegen
bin ich gerade auch auf list<> gestoßen. Wird ne Weile
dauern, bis ich mich da eingelesen habe.vector ist wie ein Array, list ist eine "klassische" verkettete Liste. Normalerweise sollte man immer mit einem vector anfangen.
Melanie_27 schrieb:
Bleibt dann nur noch das Problem, wie ich eine list<Personen> in eine list<gruppen> bringe

Dazu hat Bassmaster ja schon fertigen Code geliefert - aber ich schreibe noch ein wenig dazu: Kennst du dich auch schon ein wenig mit Klassen aus? Irgendwie hast du da noch einen Denkfehler. Zu einer Gruppe gehört eine Liste von Personen. Da ist es völlig unerheblich, wie du die Gruppen organisiert hast. "Gruppe" ist eine Klasse. Wenn etwas "zu dieser Klasse gehört", bietet es sich an, dies als Membervariable der Klasse zu modellieren. Somit braucht "Gruppe" ein Member std::vector<Person> - fertig. Jetzt hat jede Gruppe eine Liste von Personen.
viele Grüße
Felix
-
Hey, ich komme ja gar nicht mehr mit dem Lesen und Nachvollziehen hinterher

Vielen vielen Dank. Mit Klassen kenne ich mich eigentlich schon aus.
Ich werde jetzt zuerst einmal versuchen alles zu verstehen und nach zu programmieren. Ihr seid wirklich spitze.
-
Gern geschehen. Dann viel Erfolg - und bei Fragen kannst du dich natürlich jederzeit hier melden...
-
#include <iostream> #include <vector> #include <string> using namespace std; //-------------------------------------------------------------- //-------------------------------------------------------------- class PersonenListe { public: string GetName(); PersonenListe :: PersonenListe(string n); private: string Name; }; vector<PersonenListe>Personen; PersonenListe :: PersonenListe(string n) : Name(n) { } void hinzufügenPerson( string n ) { Personen.push_back( PersonenListe(n) ); // Die Daten (string n) werden mithilfe des Konstruktors PersonenListe :: PersonenListe(string n); } // in den Vector Personen gepusht string PersonenListe :: GetName() { return Name; } //-------------------------------------------------------------- //-------------------------------------------------------------- class Gruppenliste { public: string GetGroupname(); Gruppenliste::Gruppenliste(string name); vector<PersonenListe>Personen; private: string GName; }; vector<Gruppenliste>Gruppen; Gruppenliste :: Gruppenliste(string name): GName(name) { } void hinzufügenGruppe( string name ) { Gruppen.push_back( Gruppenliste(name) ); // Die Daten (string n) werden mithilfe des Konstruktors PersonenListe :: PersonenListe(string n); } // in den Vector Personen gepusht string Gruppenliste :: GetGroupname() { return GName; } //main------------------------------------------------------------- int main() { hinzufügenGruppe("GruppeA"); hinzufügenGruppe("GruppeF"); hinzufügenGruppe("GruppeU"); for (int i=0; i<=Gruppen.size()-1; i++) cout<<Gruppen[i].GetGroupname()<<endl; Gruppen[0].Personen.hinzufügenPerson("Andrea"); // <- Hier ist der Wurm drin :( cout<<endl; system("PAUSE"); return 0; }Hey ihr, wie ihr sehen könnt war ich fleißig. Ich habe hierbei aber jetzt noch das Problem, dass ich in der einzelnen Gruppe keine Personen anlegen kann. Ich weiß aber nicht, was ich falsch mache

/edit pumuckl: cpp-Tags spendiert. Demnächst bitte selber machen!

-
Hallo Melli,
als erstes solltest du cpp-Tags verwenden, wenn du hier Code postest, weil das sonst nicht gut lesbar ist. Dann ist "hier ist der Wurm drin" keine gute Fehlerbeschriebung. Was passiert? Was sollte deiner Meinung nach passieren? Welche Fehlermeldung kommt vom Compiler?
Dann bist du mit deinen Klassen irgenwie durcheinandergekommen. Du hast eine Klasse "Gruppenliste". Wofür benötigst du die? Ich glaube, du hast den Code von Bassmaster nicht richtig verstanden.
Ich gebe dir mal ein wenig Struktur:
class Person { public: explicit Person(const std::string& name) : m_name(name) {} const std::string& GetName() const {return m_name;}; private: std::string m_name; }; class Gruppe { public: explicit Gruppe(const std::string& name) : m_name(name) {} const std::string& GetName() const {return m_name;}; void AddPerson(const Person& person) {m_personen.push_back(person);}; private: std::string m_name; std::vector<Person> m_personen; }; int main() { std::vector<Gruppe> gruppen; gruppen.push_back(Gruppe("Frauen")); gruppen.push_back(Gruppe("Maenner")); gruppen[0].AddPerson(Person("Andrea")); gruppen[0].AddPerson(Person("Melli")); gruppen[1].AddPerson(Person("Thomas")); gruppen[1].AddPerson(Person("Felix")); return 0; }
-
Dein Quellcode und die Bezeichner sind total verwirrend.Melanie_27 schrieb:
class PersonenListe { public: string GetName(); PersonenListe(string n); private: string Name; }; // ... Gruppen[0].Personen.hinzufügenPerson("Andrea");Wieso hat die Liste einen Namen. Eine Person soll einen Namen haben, aber die Liste doch nicht.
Melanie_27 schrieb:
void hinzufügenGruppe( string name ) { Gruppen.push_back( Gruppenliste(name) ); } // ... hinzufügenGruppe("GruppeA"); hinzufügenGruppe("GruppeF"); hinzufügenGruppe("GruppeU");Das ist doch redundant.
std::vectorhat doch bereits so eine Funktion. Außerdem hast du mit dieser Methode nun eine globale VariableGruppenan der Backe.
-
Ahhh, ich bin so dumm

Ich sitz jetzt gerade an dem Code von Felix und bin zumindest mal in der Lage Gruppen und darin Personen anzulegen
for(int i=0; i<=gruppen.size()-1; i++) { cout<<gruppen[i].GetName()<<endl; //Das funktioniert bestens } for(int i=0; i<=gruppen[0].m_personen.size()-1; i++) //Das kennt er nicht { //weil m_personen privat ist cout<<gruppen[0].m_personen[i].GetName()<<endl; //Das folglich auch nicht. }Aber wie kann ich jetzt die Personen wieder auslesen? m_personen ist private. Wie kann ich die Größe des Personen-Vektors bestimmen und wie kann ich seinen Namen auslesen?
O man, ihr lacht mich bestimmt schon aus
Ich danke euch.
-
Denk doch mal objektorientiert

void Gruppe::Print() const { cout << "Gruppe '" << m_name << "':\n"; // hier kommt die Ausgabe des vectors }
-
Ok, ich hab es einfach public gemacht und es funktioniert :)) Ansonsten hätte ich wohl eine Methode schreiben müssen, die mir m_person ausspuckt

Hab ich Recht oder nicht ? :)))
-
Sowas durch "public-machen" zu lösen ist nicht sonderlich schön, es wiederspricht fundamental dem Konzept der Kapselung von Daten. Eine Lösung habe ich ja bereits zeitgleich mit dir gepostet.
Angenommen, du möchtest irgendwann den vector durch eine andere Struktur ersetzen, dann genügt es, wenn du die "Print()"-Methode änderst. Wenn du einfach den vector public machst, musst du in mühsamer Kleinarbeit alle Stellen im Code ändern, wo du darauf zugreifst.
-
Hääh? Aber das was du gepostet hast, hat doch nichts mit m_personen zu tun? Ich möchte ja die Personen ausgeben, die eine Gruppe hat.
Wie geht das dann, wenn ich std::vector<Person> m_personen; in der Klasse Gruppe bei private stehen hab???
-
Melanie_27 schrieb:
Hääh? Aber das was du gepostet hast, hat doch nichts mit m_personen zu tun? Ich möchte ja die Personen ausgeben, die eine Gruppe hat.
Wie geht das dann, wenn ich std::vector<Person> m_personen; in der Klasse Gruppe bei private stehen hab???Hast Du den Kommentar in felix' Code überlesen?

Wenn Du die Personen in einer Gruppe ausgeben möchtest, kannst Du doch eine Funktion "Ausgabe" in der Klasse Gruppe schreiben, die über den privaten Vector m_personen iteriert.
Oder Du bietest in der Klasse Gruppe eine Get-Methode für eine bestimmte Person (nach Index) oder den gesamten Vector an, und nutzt diese statt des privaten m_personen.
-
[offtopic]
Kaum ist ein Benutzername weiblich wird hier mit Code umsich geschmissen, wäre er männlich gewesen gäbe es mit sicherheiten schon die ein oder andere Moralpredigt
[/offtopic]
-
Cyres schrieb:
[offtopic]
Kaum ist ein Benutzername weiblich wird hier mit Code umsich geschmissen, wäre er männlich gewesen gäbe es mit sicherheiten schon die ein oder andere Moralpredigt
[/offtopic]nein, ich zumindest bin
immermeistens freundlich