Ungleiche Werte zweier Mengen bestimmen und abspeichern
-
Hallo,
ich schreibe gerade ein Programm, dass ungleiche Werte zweier Mengen bestimmen und abspeichern soll.
Zum Beispiel: Menge A(1,2,3), Menge B( 1,4,5 ), C = A + B = (2,3,4,5)Mein Lösungsansatz funktioniert leider nicht immer. Mit den Werten im main gibt es eine Ausgabe wie folgt: -842150451 2.
2 ist schon richtig, aber was ist mit 4? Ich habe das Programm schon mehrmals mit Prozedurschritten durchlaufen und konnte keine Fehler finden. Ich habe nur den betreffenden Abschnitt kopiert. Die += Operator Überladung, print() und die Konstruktoren gibt es schon. Die Kommentierten Zeilen sind der zweite Teil der Überladung. Momentan sollten nur 2 und 4 abgespeichert werden.
set <T> operator +( set s ) { int i,j,g = 0; T *r = NULL; int h = 1; /* for( i = 0; i < length;i++) { h = 1; for( j = 0; j<(s.length); j++ ) if (s.m[j] == m[i]) { h = 0; } if( h != 0 ) { r = new T[1]; r[g++] = m[i]; } }*/ for( i = 0; i < s.length;i++) { h = 1; for( j = 0; j < length; j++ ) if (m[j] == s.m[i]) { h = 0; } if( h != 0 ) { r = new T[1]; r[g++] = s.m[i]; } } m = r; this->length = g; return *this; } }; void main(void) { set <int> a; set <int> b; set <int> c; a += 5; a += 6; a += 8; b += 4; b += 6; b += 8; b += 2; c = a + b; c.print(); cin.get(); }Könnt ihr mir bitte helfen?
Vielen Dank
randy2
-
Das ist aber nicht die std::set<..>, die du dort verwendest?
Ansonsten empfehle ich dir mal einen Blick in den Header <algorithm> - dort gibt es eine Reihe Funktionen, die mit set_... beginnen und solche Berechnungen erledigen.
-
Nein, es handelt sich um ein template <typename T>. Diese Berechnung ist als Übung gedacht.
-
Aus den Codeschnipseln würde ich schliessen, dass du das Set in einem Array m speicherst. Im operator+ verwendest du r, um das Zwischenergebnis zu speichern. Dann kann es aber nicht sinnvoll sein, r immer wieder mit new T[1] ein einelementiges Array zuzuweisen. Ausserdem veränderst du this, d.h. in a ist nach der Addition des Ergebnis enthalten. Ob das Ergebnis in der Zuweisung an c wenigstens richtig kopiert wird kann man aus dem vorhandenen Code nicht erkennen.
-
randy2 schrieb:
Nein, es handelt sich um ein template <typename T>.
std::set ist auch ein "template<typename>"

Der einfache Vorschlag: Verwende zur Speicherung einen STL-Container und setze die ganzen Mengen-Operationen mit den set_... Algorithmen der STL um.
Wenn du es selber programmieren willst: Sorg dafür, daß die einzelnen Mengen immer sortiert sind, dann kannst du parallel durch beide Mengen iterieren und die Werte vergleichen.
-
@manni66
Ich verstehe nicht, warum es nicht sinnvoll ist, r immer ein einelementiges Array zuzuweisen. Jeder Wert, der die Bedingungen erfüllt, wird in r nacheinander eingetragen. Mit Vollendung der Schleife werden alle Werte in m übertragen (So soll es zumindest sein). Das mit this werde ich ändern, allerdings sollte in C trotzdem die richtigen Werte stehen. Hier der ganze Code:
#include <iostream> #include <string.h> using namespace std; template <typename T> class set { T *m; int length; public: set(){m = NULL;length = 0;} set ( T *mm ) { m = new T[length = mm->length]; for( int i = 0; i < length; i++ ) { m[i] = mm[i]; } } set <T> &operator += (T b ) { length++; if( !m ) { m = new T[1]; m[0] = b; return *this; } T *p = new T[length]; for( int i = 0; i < length-1; i++) { p[i] = m[i]; } p[length-1] = b; delete[] m; m = p; return *this; } void print(void) { for( int i = 0; i < length; i++ ) { cout << " " << m[i]; } } set <T> operator +( set s ) { int i,j,g = 0; T *r = NULL; int h = 1; /* for( i = 0; i < length;i++) { h = 1; for( j = 0; j<(s.length); j++ ) if (s.m[j] == m[i]) { h = 0; } if( h != 0 ) { r = new T[1]; r[g++] = m[i]; } }*/ for( i = 0; i < s.length;i++) { h = 1; for( j = 0; j < length; j++ ) if (m[j] == s.m[i]) { h = 0; } if( h != 0 ) { r = new T[1]; r[g++] = s.m[i]; } } m = r; this->length = g; return *this; } }; void main(void) { set <int> a; set <int> b; set <int> c; a += 5; a += 6; a += 8; b += 4; b += 6; b += 8; b += 2; c = a + b; c.print(); cin.get(); }Das wusste ich nicht, ich habe gerade erst mit den Templates begonnen. Das mit den Sortieren ist ein guter Ansatz, den ich verfolgen werde.
Gruß
randy2
-
randy2 schrieb:
ich schreibe gerade ein Programm, dass ungleiche Werte zweier Mengen bestimmen und abspeichern soll.
Zum Beispiel: Menge A(1,2,3), Menge B( 1,4,5 ), C = A + B = (2,3,4,5)Du könntest dir auch den STL-Algorithmus
std::set_symmetric_difference()auf www.cplusplus.com anschauen.randy2 schrieb:
void main(void)main()mussintzurückgeben, was anderes ist nicht standardkonform, auch wenn dein Compiler hier tolerant sein mag.randy2 schrieb:
#include <string.h>Nimm entweder
<string>(für die Klassestd::string) oder<cstring>(für die C-Zeichenkettenfunktionen).
-
Noch ein anderer Punkt, ich würde für diese Operation nicht den +Operator überladen. Intuitiv würde ich sage, dass diese Operation entweder die Vereinigung ist, oder wie in der Mathematik auch üblich, eine Art elementweise Addition.
Und der Tipp mit symmetrischer Differenz ist auch sehr gut. Schreibe doch einfach operator+ als Vereinigung um, operator/ als Differenz und operator- als Schnitt. Dann kannst du die symmetrische Differenz viel einfacher Implementieren

set symm_diff(set A, set B) { return (A + B) / (A - B); }
-
bmario schrieb:
Schreibe doch einfach operator+ als Vereinigung um, operator/ als Differenz und operator- als Schnitt.
Aber
-als Schnitt? Minus kommutativ? Finde ich auch nicht besonders intuitiv, zumal man viel schneller an Differenz (mathematisch \) denkt. Ich würde wenn überhaupt folgende Überladungen wählen. Sicherer sind natürlich benannte Funktionen.&Schnitt: Elemente, die in A und B sind|Vereinigung: Elemente, die in A oder B sind^Symmetrische Differenz: Elemente, die entweder in A oder B sind
-
randy2 schrieb:
@manni66
Ich verstehe nicht, warum es nicht sinnvoll ist, r immer ein einelementiges Array zuzuweisen. Jeder Wert, der die Bedingungen erfüllt, wird in r nacheinander eingetragen. Mit Vollendung der Schleife werden alle Werte in m übertragen (So soll es zumindest sein).
So funktioniert es aber leider in C++ nicht. r ist immer das letzte einelementige Array, das du erzeugt hast. Was du erreichen möchtest geht mit std::vector und push_back.Mit "nackten" Arrays müsstest du vorgehen wie in deiner operator+= Funktion.
-
Danke, das war der Fehler. Ich habe nun im + Operator ein ganzes Objekt erzeugt, an dem der += Operator angewendet wird.
Gruß
randy2