Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » variable Mengen in C++

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ] [ 5 ]
020
13.07.2003, 21:47 Uhr
0xdeadbeef
Gott
(Operator)


Auf die STL muss man sich erst mal einlassen. Es erfordert halt ein bisschen Einarbeitung, aber normalerweise fährst du damit - wenn du weißt. was du tust - besser. Sowohl bei der Entwicklungszeit als auch bei der Performance. Überleg mal - wenn du deine Klasse jetzt auf Strings ausweiten willst, musst du den ganzen Code umschreiben. Im Endeffekt hast du dann nachher tausend Klassen, die genau dasselbe machen - und wenn sich an einer Stelle im Code was ändert, musst du es an tausend Stellen hinschreiben.
Oder auch die Iterator-Geschichte - wenn ich die Schnittmenge jetzt zum Beispiel nicht nach stdout, sondern in ein weiteres set schreiben wollte, könnte ich mir einfach einen output-iterator auf ein neues set-Objekt bauen und das Zeug da reinschreiben. Oder auch in einen Vektor. Oder in eine Datei. Oder sonstwohin. Die STL ist schon durchgestylt, und ich will sie nicht mehr missen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
021
13.07.2003, 23:54 Uhr
Pablo
Supertux
(Operator)


Wenn du STL vermeiden willst, kannst du dann mit einer Single Linked List (verketteten Listen) implementieren, da hat man auch eine Variable Länge und die Einfüge und Entfere Operationen laufen in O(n) und wenn man sehr geschickt implementiert (mit einem zusätzlichen Zeiger auf das letzte Element und eventuell auch noch einem auf den aktuellen Knoten) kann sogar in konstanter Zeit laufen.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 13.07.2003 um 23:54 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
022
14.07.2003, 08:05 Uhr
~Jerome83
Gast


danke erstmal für die mühe.

werd das heute nachmittag mal testen , was muß ich denn noch verändern/machen? du meintest es wäre nioch nicht fertig...

werd erstmal meine "recht"-klausur schreuiben gehen, ich hasse stress.... wer tut das nicht...

so denn, vielen dank, bis später.

jerome.....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
023
14.07.2003, 12:29 Uhr
Oliver
S2-Pixelgeneral


@Jerome:
Probier mal das kleine Programm aus:



C++:
#include <iostream>
using namespace std;

class Menge
{
    int* elemente;
    int anzahl;
public:
    Menge();
    ~Menge(){delete [] elemente;}
    Menge(const int elements[],const int &anzahl);
    Menge(Menge &vorh);
    void Add(int element);                                // fügt Element hinzu
    Menge Schnittmenge(Menge &meng2);       // bildet Schnittmenge
    int GetAnzahl() const;
    int GetElemente(const int &index) const;    
              Menge &operator=(Menge &menge2);          // Zuweisungsoperator
    bool IsVorhanden(const int &element);         // Ist ein Element in der Menge vorhanden?
    Menge Vereinigungsmenge(Menge menge2);// Vereiniguns menge
    Menge operator+(Menge &menge2);            // addiert zwei Mengen (bildet eine Vereinigunsmenge)
    bool operator==(Menge& menge2);              // sind die Mengen gleich?
    bool ifTeilmenge(Menge &teilmenge);           // ist der Parameter eine Teilmenge?
    void ShowMenge() const;                            // gibt Menge aus
    
};




Menge::Menge(const int elements[],const int &anzahl2)
{
    elemente=new int[anzahl2];
    anzahl=anzahl2;
    for(int i =0;i<anzahl;i++)
        elemente[i] = elements[i];
    anzahl = anzahl2;
}

Menge::Menge()
{
    elemente=0;
    anzahl=0;
}

bool Menge::IsVorhanden(const int &element)
{
    for(int i =0;i<anzahl;i++)
        if(elemente[i]==element)
            return 1;
    return 0;
}


int Menge::GetAnzahl() const
{
    return anzahl;
}

int Menge::GetElemente(const int &index) const
{
    return elemente[index];
}

Menge::Menge(Menge &vorh)
{
    anzahl = vorh.GetAnzahl();
    elemente = new int[anzahl];
    for(int i =0;i<anzahl;i++)
        elemente[i] = vorh.GetElemente(i);
}

Menge &Menge::operator=(Menge &menge2)
{
    anzahl=menge2.GetAnzahl();
    if(anzahl) delete [] elemente;
    elemente = new int[anzahl];
    for(int i=0;i<anzahl;i++)
        elemente[i] =  menge2.GetElemente(i);
    return *this;
}

Menge Menge::operator+(Menge &menge2)
{
    Menge erg;
    int i;
    for(i=0;i<anzahl;i++)
        if(!erg.IsVorhanden(elemente[i])) erg.Add(elemente[i]);
    for(i=0;i<menge2.GetAnzahl();i++)
        if(!erg.IsVorhanden(menge2.GetElemente(i))) erg.Add(menge2.GetElemente(i));
    return erg;
}



void Menge::Add(int element)
{
    Menge merke(*this);
    anzahl++;
    if(anzahl) delete [] elemente;
    elemente= new int[anzahl];
    for(int i = 0;i<anzahl-1;i++)
        elemente[i]=merke.GetElemente(i);
    elemente[anzahl-1]=element;
}

Menge Menge::Vereinigungsmenge(Menge menge2)
{
    Menge erg;
    int i;
    for(i=0;i<anzahl;i++)
        if(!erg.IsVorhanden(elemente[i])) erg.Add(elemente[i]);
    for(i=0;i<menge2.GetAnzahl();i++)
        if(!erg.IsVorhanden(menge2.GetElemente(i))) erg.Add(menge2.GetElemente(i));
    return erg;
}



Menge Menge::Schnittmenge(Menge &meng2)
{
    Menge erg;
    for(int z =0;z<meng2.GetAnzahl();z++)
     for(int i = 0;i<anzahl;i++)
         if(elemente[i] == meng2.GetElemente(z)) erg.Add(elemente[i]);
    return erg;
}

bool Menge::operator==(Menge &menge2)
{
    bool merke=0;
    if(anzahl!=menge2.GetAnzahl()) return 0;

    for(int i =0;i<anzahl;i++)
    {
        for(int z =0;z<anzahl;z++)
            if(elemente[i]==menge2.GetElemente(z)) merke=1;
        if(!merke) return 0;
        merke=0;
    }
    return 1;
}

bool Menge::ifTeilmenge(Menge &teilmenge)
{
    bool merke=0;
    if(teilmenge.GetAnzahl()>anzahl) return 0;
    for(int i=0;i<teilmenge.GetAnzahl();i++) {
        for(int z=0;z<anzahl;z++)
            if(teilmenge.GetElemente(i)==elemente[z]) merke=1;
        if(!merke) return 0;
        merke=0;}
    return 1;
}

void Menge::ShowMenge() const
{
    if(anzahl<1) cout << "{}";
    cout << "{";
    for(int i =0;i<anzahl-1;i++)
        cout << elemente[i] << "; ";
    cout << elemente[anzahl-1] << "}";
}


        

    



int main(){

    Menge a;
    Menge b;
    Menge e;
    int wieviel;
    int zwisch;


    
    cout << "/ Das Mengenprogramm /\n\n\n";
    cout << "Schritt 1: Initialisieren der Mengen\n\n";
    cout << "Wie viele Elemente sollen der Menge A zugeordnet werden: ";
    cin >> wieviel;
    cout << "Bitte geben Sie jetzt Ihre " << wieviel << " Elemente an!\n";
    for(int i =0;i<wieviel;i++) {
        cin >> zwisch;
        a.Add(zwisch); }
    cout << "\n\nWie viele Elemente sollen der Menge B zugeordnet werden: ";
    cin >> wieviel;
    cout << "Bitte geben Sie jetzt Ihre " << wieviel << " Elemente an!\n";
    for(i =0;i<wieviel;i++) {
    cin >> zwisch;
    b.Add(zwisch); }
    cout << "Mengen wurden erfolgreich initialisiert!\n\n";
    cout << "A = "; a.ShowMenge(); cout << "\n";
    cout << "B = "; b.ShowMenge(); cout << "\n\n\n";

    cout << "Schritt 2: Informationen ueber die Mengen\n\n";
    e = a.Schnittmenge(b);
    cout << "Die Schnittmenge von A und B: "; e.ShowMenge();
    e = a+b;
    cout << "\n\nDie Vereinigunsmenge von A und B: "; e.ShowMenge();
    if(a==b) cout << "\n\nA und B sind gleich.\n";
    if(a.ifTeilmenge(b)) cout << "\n\nB ist eine Teilmenge von A.\n";
    if(b.ifTeilmenge(a)) cout << "\n\nA ist eine Teilmenge von B.\n\n";
    cin.get();
return 0;
}



Die einzige große Schwäche an dem Programm ist, dass wenn eine Menge 0 Elemente hat, es dann abstürzt.
Aber sonst funktionierts wunderbar.
Sicherlich könnte man noch den != Operator hinzufügen, aber das ist eigentlich fast egal.


@Heiko und Oxdeadbeef:

Klar wär eine Templateklasse besser gewesen, aber da hätte er's ja sicher gar nicht verstanden.
Außerdem sind Templates auch nicht so mein Ding .
Und ich habe auch eigentlich keine große Lust mich damit zu beschäftigen.
Wenn man was nicht braucht, verlernt man es auch, weil man es ja nie anwendet und ich habe eigentlich noch keine Situation erlebt, wo ich jetzt unbedingt Templates brauche.
--
Demokratie ist die Diktatur der Mehrheit.

www.siedler25.org/ ( Siedler2 - Remake )

Dieser Post wurde am 14.07.2003 um 13:06 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
024
14.07.2003, 14:31 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat:
Oliver Müller postete

...
Außerdem sind Templates auch nicht so mein Ding .
Und ich habe auch eigentlich keine große Lust mich damit zu beschäftigen.
Wenn man was nicht braucht, verlernt man es auch, weil man es ja nie anwendet und ich habe eigentlich noch keine Situation erlebt, wo ich jetzt unbedingt Templates brauche.


Herzliches Beileid. C++ ohne Templates ist wie eine Schnecke ohne Haus, bzw. wie Ketchup ohne Fritten.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
025
14.07.2003, 14:47 Uhr
~Jerome83
Gast


super sache das programm, funktioniert so wie es soll, jedenfalls fast. aber das problem mit der dynamischen speicherfreigabe ist damit nicht gelöst.

der benutzer soll nicht vorher sagen "4 elemente ´sollen in die erste menge und 3 in die zweite menge" er soll gefragt weren "wollen sie ein element hinzufügen?" und dann "ja" antworten und eine zahl eingeben. dann wieder gefragt werden usw.! geht das da irgendwie noch einzuauen?

und was ist bool für ein datentyp? davon hab ich nie was gehört und den haben wir auf jeden fall nie "gelernt". geht das nicht auch mit int zu lösen? oder nem anderen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
026
14.07.2003, 14:50 Uhr
ao

(Operator)



Zitat:
~Jerome83 postete
und was ist bool für ein datentyp? davon hab ich nie was gehört und den haben wir auf jeden fall nie "gelernt".

Augenblick mal, mir kommt da ein schlimmer Verdacht. Lernst du C oder C++?

Du hast zwar im ersten Posting was von Klassen geschrieben (Indiz für C++), aber wenn du jetzt sagst, daß du kein bool kennst, wird man doch wohl noch mal fragen dürfen.

ao

Dieser Post wurde am 14.07.2003 um 14:53 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
027
14.07.2003, 15:08 Uhr
Pablo
Supertux
(Operator)


Gute Frage von ao, was lernst du, c oder c++. Wenn du c lernst, dann kannst du die Lösung von Oli nehmen, weil das C++ ist. In C gibt es keine Klassen oder Templates und wenn du einen Speicher haben willst, dessen Länge nicht fest ist,d.h, dass sie sich ändert während des Verlaufs des Programmes, kannst du keine Arrays nehmen, und wenn schon dann laufen die Einfüge Operationen in O(n), in Omega(n) sogar, wenn man nicht gut implementiert. In C kann man sowas machen wie:


Code:
scanf("%d", &var);
int array[var+1]:


erstens weil das Array vor dem scanf deklariert werden muss und zweitens kann man nicht mit einer Variable ein Array initialiseren.

Wenn du trotzdem eine variable Länge haben willst, dann musst (kannst) du verkette bzw. doppelverkette Listen nehmen. Bsp:


C++:
typedef struct
{
  int content;
  struct LISTE* nextNode;
} LISTE;


--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
028
14.07.2003, 18:24 Uhr
~Jerome83
Gast


natürlich c++... bool heißt das nur TRUE oder FALSE zurückgegeben wird, also 1 oder 0, richtig???


aber aufgrund des sehr umfangreichen quelltextes und der abweichung von meiner vorstellung hab ich mich vom skript leiten lassen und will jetzt so an das programm rangehen, dass ich die menge als konkreten datentyp verwende!

das könnte ungefähr so aussehen (der compiler meckert nicht, is schonmal gut...):


C++:
#include <iostream.h>

class Menge {
  public:
    Menge ();              // leere Menge
    Menge (int);           // einelementige Menge
    Menge (const Menge &); // Kopierkonstruktor
    ~Menge ();             // Destruktor

    Menge  &operator =   (const Menge &);       // Zuweisung
    Menge   operator +   (const Menge &) const; // Vereinigung
    Menge   operator *   (const Menge &) const; // Schnitt
    
  private:
    class Knoten {
    public:
      Knoten   ();
      Knoten   (int, Knoten *);
      ~Knoten  ();
      int      wert;
      Knoten * n;
    };
    Knoten *anfang;  // Start der verketteten Knoten
                     //... eventuelle Hilfsroutinen ...
  };

void main (void)
{


};


jetzt stoße ich aber gleich bei dem zuweisungsoperator auf das problem, dass ich es nicht hinbekomme, ein objekt vom typ menge zu erstellen und diesem objekt ein element "Knoten" zuzuweisen. Knoten soll den wert des elements enthalten und nen verweis auf den nachfolger.

wie mach ich das????

-- 0xdeadbeef: Edit (cpp-tags eingefügt)

Dieser Post wurde am 14.07.2003 um 18:53 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
029
14.07.2003, 19:19 Uhr
Oliver
S2-Pixelgeneral


Verketette Listen

In meinem Buch steht eine Klasse (bzw. mehrere) für verkettete Listen. Aber das ist 5 Seiten lang.
Und das ganze noch mit templates 9 oder 10.
Wer soll da noch durchblicken.

@Jerome:


Zitat:
und will jetzt so an das programm rangehen, dass ich die menge als konkreten datentyp verwende!


Was willst du damit sagen?
Eine Klasse ist sowas wie ein Datentyp.

Das mit den fragen, ob er noch was zu Menge hinzufügen will, könntest du so machen.


C++:
bool add;
int element;
while(1)
{
cout << "Wollen Sie noch ein Element hinzufügen (drücken Sie 1 für ja und 0 für nein): ";
cin >> add;
if(!add) break;
cout << "Bitte geben Sie Ihr Element ein: ";
cin >> element;
a.Add(element);
}



Noch was: Ich wird nicht gleich anfangen verkettete Listen zu programmieren, wenn man nicht richtig die Klassen kapiert hat.

Und das mit dem *operator: Da brauchst du im Prinzip nur die Funktion Vereinigunsmenge in operator* umzubenennen.

Und was soll das mit der Klasse Knoten???
--
Demokratie ist die Diktatur der Mehrheit.

www.siedler25.org/ ( Siedler2 - Remake )
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ] [ 5 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: