Wie kann ich in einer Methode zwei Mengen vereinen und die Dritte Menge als Rückgabe liefern ?
-
Hallo,
Ich habe ein ziemlich nervenaufreibendes Problem.
Ich habe zwei Klassen.Liste und Node.
Das Programm soll zwei Mengen (Liste mit integer Werten) vereinen und die daraus resultierende dritte Menge ausgeben.Wie ihr unten im Code sehen könnt habe ich die Mengen vereint, und auch noch überprüft , damit jedes element nur einmal vorkommt. Aber ich schaffe es einfach nicht die resultierende Menge zurückzugeben, damit ich sie im Main dann ausgeben kann. Im Moment bleibtmir nichts anderes übrig, als die Ausgabe direkt in der Methode Vereinigung zu machen.
Ich brauche das Programm für eine Prüfung, und so möchte ich es nicht abgeben, da es einfach syntaktisch unschön ist, die Ausgabe direkt in der Methode aufzurufen. Wäre toll wenn mir jemand helfen könnte.
Ich möchte es so haben, daß die Methode Vereinigung mir eine Menge c Liefert(Vereinigung von a und b).
Und im Main möchte ich dann die Ausgabe von c erst aufrufen.[code]
#include <iostream.h>class PRFGNode
{
public:
unsigned int elem;
PRFGNode *next;
PRFGNode(int e=0, PRFGNode *n=0):elem(e),next(n){}};
class Set
{
public:
Set():root(0) {}
Set(int){Set *first; first=new Set();} //leere Menge
~Set(); //Destruktor, löscht alle Listenelemente
void insert_at_first(unsigned int x); //einfügen in Liste
void Ausgabe();
void Vereinigung(Set &b); //UP für die Vereinigung
bool ist_in(unsigned int y); //Funktion die true zurückliefert, wenn y in Liste
private:
PRFGNode *root;};
void Set::insert_at_first(unsigned int x) //Einfuegen am Listenbeginn
{root=new PRFGNode(x,root);
}
void Set::Vereinigung(Set &b)
{
Set c;
PRFGNode *h1,*h2;
bool test=false;
h1=root; // Zeiger aufs 1 Element der Menge a, siehe Aufruf im void main ( a.Vereinigung(b) )
h2=b.root; // Zeiger aufs 1 Element der Menge b, diese wird als Parameter übergebenwhile(h2!=0) //zunächst werden in die neue Menge c alle Elemente von b hineinkopiert
{
c.insert_at_first(h2->elem);
h2=h2->next; //weiter in der Liste
}while(h1!=0) //hier werden die noch fehlenden Elemente aus a in c eingefügt
{
if(b.ist_in(h1->elem)) // es wird mit der Funktion "ist_in" geschaut, welche noch fehlen
test=true;
else
test=false;if(test==false) //wenn das Element "h1->elem" von Menge a noch nicht in der Menge b, dann in c einfügen
c.insert_at_first(h1->elem); //einfügen in c
h1=h1->next; //mit next-Zeiger kommt man in der Liste weiter, (ähnlich i++)
} //danach beginnt while-Schleife erneutc.Ausgabe(); //Ausgabe der Vereinigungsmenge, jedoch wird diese Menge nicht zurückgeliefert
}
bool Set::ist_in(unsigned int y) //überprüfen ob y in Liste
{
PRFGNode *hilf;
bool test=false; //bool-Variable test, hat Werte "true" oder "false"
hilf=root;while (hilf!=0)
{
if((hilf->elem)==y)
test=true;
else
test=false;hilf=hilf->next;
}
return test;
}void Set::Ausgabe() //Ausgabe der Liste
{
int anz=0,i=0;
PRFGNode *aktuell;aktuell = root;
while (aktuell != NULL)
{
i++;
cout << "\n" << "Das " << i << ". Element hat den Wert " << (*aktuell).elem << "."<<endl;
aktuell = (*aktuell).next;
}}
Set::~Set() //Destruktor
{
PRFGNode *voriges;
PRFGNode *aktuell;aktuell=new PRFGNode;
voriges=new PRFGNode;
voriges=NULL;aktuell=root;
while(aktuell!=0)
{voriges=aktuell;
aktuell=aktuell->next;
delete voriges;
}}
void main()
{
Set a;
Set b;
Set c;a.insert_at_first(8);
a.insert_at_first(9);
a.insert_at_first(5);b.insert_at_first(8);
b.insert_at_first(3);
b.insert_at_first(2);//a.Ausgabe();
if(a.ist_in(6)) //dh wenn true zurückgegeben wird, dann ist es in der Liste
cout<<"\n"<<"Das Element ist in der Liste";
else
cout<<"\n"<<"Ist nicht drin"<<endl; //wenn 6 nicht in Liste, dann Meldung...a.Vereinigung(b); //es wird die Vereinigungs-Menge ausgegeben, siehe UP: void Set::Vereinigung(Set b)
//ist nicht genau das, was in der Angabe gefordert wurde, da dort die Vereinigung zurückgeliefert werden sollte, mit return- funkt. aber irgendwie nicht!!!!}
-
Es sieht ja fast so aus, als sollten wir deine Ausaufgaben machen, und du bekommst dann die guten Noten dafür.
So ist das Forum nicht gedacht.Nichts für ungut
Dieter
-
Das Programm funktioniert bereits. Ich will nur die Methode verfeinern.
Und darauf bekomme ich keine Note, denn die Klausur, in welcher dieses Programm zu codieren war, habe ich schon geschrieben. Mich ärgert im nach hinein nur, daß ich es nicht schaffe eine Methode zu schreiben, in der zwei Mengen a und b zu einer dritten Menge c vereinigt werden. Und die Methode soll die Vereinigte Menge c zurückliefern.Und es soll nur in einer einfach verketteten Liste gelöst werden.(Keine doppelt verkettete Liste).
Ich habe es mit return versucht, aber ohne Erfolg.
Es ist mir schon klar, daß das Beispiel nicht besonders schön codiert ist.
Bin ja für jede Hilfe dankbar. Ich belästige euch auch nur deswegen, da ich schon seit einer Woche versuche das Problem zu lösen, aber ich komme einfach nicht weiter. Habe schon alle Ressourcen ausgenutzt die mir zur Verfügung stehen.mfg Thomas
-
Dein Code der Vereinigungsmethode ist also wie folgt:
void Set::Vereinigung(Set &b) { Set c; PRFGNode *h1,*h2; bool test=false; h1=root; // Zeiger aufs 1 Element der Menge a, siehe Aufruf im void main ( a.Vereinigung(b) ) h2=b.root; // Zeiger aufs 1 Element der Menge b, diese wird als Parameter übergeben while(h2!=0) //zunächst werden in die neue Menge c alle Elemente von b hineinkopiert { c.insert_at_first(h2->elem); h2=h2->next; //weiter in der Liste } while(h1!=0) //hier werden die noch fehlenden Elemente aus a in c eingefügt { if(b.ist_in(h1->elem)) // es wird mit der Funktion "ist_in" geschaut, welche noch fehlen test=true; else test=false; if(test==false) //wenn das Element "h1->elem" von Menge a noch nicht in der Menge b, dann in c einfügen c.insert_at_first(h1->elem); //einfügen in c h1=h1->next; //mit next-Zeiger kommt man in der Liste weiter, (ähnlich i++) } //danach beginnt while-Schleife erneut c.Ausgabe(); //Ausgabe der Vereinigungsmenge, jedoch wird diese Menge nicht zurückgeliefert }Hab sie nur noch mal ausgegeben, weil man dann einen besseren Überblick über deinen Code hat
.Also ich würde es wie folgt machen:
Den Funktionskopf ändern in
Set Set::Vereinigung(Set &b) {...}In der Klassendeklaration sollte es dementsprechend auch geändert werden
class Set { ... Set Vereinigung(Set &b); ... }In der Methode selbst statt dem Ausgabeaufruf
... return c ...schreiben. Ich hoffe mal das ich nichts übersehen habe:
int main() { ... Set c; ... c = a.Vereinigung(b); c.Ausgabe(); ... return 0; }Jaja, man kann daran was verbessern, aber ich glaube, so müsste es gehen.
Habe es nicht ausprobiert. Ich hoffe, ich konnte die wenigstens ein bißchen helfen.
-
Ich habe die Änderungen wie beschrieben durchgeführt, es kommt zu keinem Fehler beim Compilieren, aber beim ausführen.
Wäre toll wenn mir da noch jemand helfen kann, denn mit der Fehlermeldung kann ich nichts anfangen.
mfg Thomas
#include <iostream> using namespace std; class PRFGNode { public: unsigned int elem; PRFGNode *next; PRFGNode(int e=0, PRFGNode *n=0):elem(e),next(n){} }; class Set { public: Set():root(0) {} Set(int){Set *first; first=new Set();} //leere Menge ~Set(); //Destruktor, löscht alle Listenelemente void insert_at_first(unsigned int x); //einfügen in Liste void Ausgabe(); Set (Vereinigung(Set &b)); //UP für die Vereinigung bool ist_in(unsigned int y); //Funktion die true zurückliefert, wenn y in Liste private: PRFGNode *root; }; void Set::insert_at_first(unsigned int x) //Einfuegen am Listenbeginn { root=new PRFGNode(x,root); } Set Set::Vereinigung(Set &b) { Set c; PRFGNode *h1,*h2; bool test=false; h1=root; // Zeiger aufs 1 Element der Menge a, siehe Aufruf im void main ( a.Vereinigung(b) ) h2=b.root; // Zeiger aufs 1 Element der Menge b, diese wird als Parameter übergeben while(h2!=0) //zunächst werden in die neue Menge c alle Elemente von b hineinkopiert { c.insert_at_first(h2->elem); h2=h2->next; //weiter in der Liste } while(h1!=0) //hier werden die noch fehlenden Elemente aus a in c eingefügt { if(b.ist_in(h1->elem)) // es wird mit der Funktion "ist_in" geschaut, welche noch fehlen test=true; else test=false; if(test==false) //wenn das Element "h1->elem" von Menge a noch nicht in der Menge b, dann in c einfügen c.insert_at_first(h1->elem); //einfügen in c h1=h1->next; //mit next-Zeiger kommt man in der Liste weiter, (ähnlich i++) } //danach beginnt while-Schleife erneut return c; //Ausgabe der Vereinigungsmenge, jedoch wird diese Menge nicht zurückgeliefert } bool Set::ist_in(unsigned int y) //überprüfen ob y in Liste { PRFGNode *hilf; bool test=false; //bool-Variable test, hat Werte "true" oder "false" hilf=root; while (hilf!=0) { if((hilf->elem)==y) test=true; else test=false; hilf=hilf->next; } return test; } void Set::Ausgabe() //Ausgabe der Liste { int anz=0,i=0; PRFGNode *aktuell; aktuell = root; while (aktuell != NULL) { i++; cout << "\n" << "Das " << i << ". Element hat den Wert " << (*aktuell).elem << "."<<endl; aktuell = (*aktuell).next; } } Set::~Set() //Destruktor { PRFGNode *voriges; PRFGNode *aktuell; aktuell=new PRFGNode; voriges=new PRFGNode; voriges=NULL; aktuell=root; while(aktuell!=0) { voriges=aktuell; aktuell=aktuell->next; delete voriges; } } int main() { Set a, b, c; a.insert_at_first(8); a.insert_at_first(9); a.insert_at_first(5); b.insert_at_first(8); b.insert_at_first(3); b.insert_at_first(2); //a.Ausgabe(); if(a.ist_in(6)) //dh wenn true zurückgegeben wird, dann ist es in der Liste cout<<"\n"<<"Das Element ist in der Liste"; else cout<<"\n"<<"Ist nicht drin"<<endl; //wenn 6 nicht in Liste, dann Meldung... c = (a.Vereinigung(b)); //es wird die Vereinigungs-Menge ausgegeben, siehe UP: void Set::Vereinigung(Set b) //ist nicht genau das, was in der Angabe gefordert wurde, da dort die Vereinigung zurückgeliefert werden sollte, mit return- funkt. aber irgendwie nicht!!!! c.Ausgabe(); return 0; }
-
Danke für eure Hilfe, ich habe das Programm fertig, und es funktioniert so wie es soll.
Ohne eure Hilfe wäre es mir schlecht ergangen.
mfg Thomas
PS: Es fehlte ein Kopykonstruktor und ein Zuweisungsoperator. Und noch ein paar Kleinigkeiten.