Datentyp map - Elemente mit Schlüssel durchlaufen



  • Guten Morgen zusammen,

    ich habe folgnde Aufgabenstellung:

    Ich soll in einer Klasse eine map definieren, die aus zwei eigenen Datentypen besteht. Der eine Datentyp ist eine Art Auftrag (ebenfalls mit Namen Auftrag), der aus Auftragsnummer, Auftragsdatum, etc. besteht.
    Der andere Datentyp soll der Schlüssel für die map werden, die Klasse soll Auftragskey heißen.

    Am Ende sollen zwei maps miteinander verglichen werden und immer wenn der Schlüssel der ersten map mit dem Schlüssel der zweiten map gleich ist, soll etwas bestimmtes passieren. Was ist eigentlich für meine Frage irrelevant.

    Wenn ich nun die map definiere, müsste sie ja so aussehen:

    map <Auftragskey, Auftrag> auftraege;

    Der Schlüssel soll nun aus den Elementen Auftragsdatum, Auftragsnummer und Filialnummer der Klasse Auftrag bestehen. Jedesmal wenn diese 3 gleich sind, soll etwas passieren.

    Was muss da in die Auftragskey-Klasse rein?
    Muss man die Klassen da irgendwie ableiten dafür oder wie geht man bei einer map vor?

    Danke im Voraus.

    Habe das bis jetzt mit vectoren gemacht, aber mein Prof meinte ich solle mir mal den Datentyp map anschauen, da dann alles schneller/effizienter läuft.



  • In einer normalen Map müssen keys ja einzigartig sein, das heißt mit find() hast d udein Problem schon gelöst.

    map<key,wert>::iterator it

    for(it = mymap.begin(); it != mymap.end(); ++it)
    {
    // first key, second wert
    if(yourmap.find(it->first) != mymap.end())
    {
    // something special
    }
    }



  • im Vergleich gehört natürlich yourmap und nicht mymap rein nach dem Ungleich.

    Eventuell noch den Gleichheitsoperator überladen wenn es nicht so geht.



  • Und was macht das jetzt genau?
    Es soll ja trotzdem Element X aus Map1 in Map2 gesucht werden.

    Wieso überhaupt die Idee mit der Auftragskey-Klasse.

    Meine Auftragsklasse enthält noch mehrere Member.
    Unter anderem Name, Geburtstag usw.

    Aber nur wenn Auftragsdatum, Auftragsnummer und Fililanummer gleich sind soll etwas passieren.



  • OK, dank MapMansAssistent habe ich das verstanden.
    Aber wenn ich die Auftragskey-Klasse nun nicht mehr brauche, wie ist dann mein zweiter Datentyp für die map?



  • Meine Auftragsklasse enthält noch mehrere Member.
    Unter anderem Name, Geburtstag usw.

    hm ... Keine Ahnung wie du das mit der Keyklasse handhabst doch die Keyklasse sollte das ganze Zusatzzeugs doch nicht enthalten, er dieht ja nur der Identifizierung (?)

    Ansonsten wie gesagt den Gleichheitsoperator überladen und eben nur auf die relevanten Elemente prüfen.

    Wenn du die Keyklasse nicht mehr brauchst dann löscht du die eben, wenn du den Key aus der Map löchst wird der Wert mitgelöscht. Ist das Ding dynamisch angelegt solltets du die Wertklasse erst einmal freigeben bevor du löchst.

    if(map.find(key) != map.end())
       {
          // (je nachdem) delete map.find(key)->second;
          map.erase(map.find(key));
       }
    

    Aber ganz im Allgemeinen finde ich es ein bischen komisch das man eine keyklasse bastelt welche einfach nur ein paar weitere Werte aus der Wertklasse speichert. Wenn du das mit vectoren hinbekommen hast kannst du direkt bei denen bleiben für diese Aufgabe.
    Dort gibt es auch find, erase und die Möglichkeit sequentiell mit Iteratoren durchzulaufen.



  • Meine Auftragsklasse sieht so aus:

    class Auftrag
    {
    	friend class Auftragsliste;
    
    	private:
    		int filialnummer;
    		int auftragsnummer;
    		string auftragsdatum;
    		string name;
    		string vorname;
    		string geburtsdatum;
    		string strasse;
    
    	public:a
    		Auftrag(string s); // 1. Konstruktor, zerpflückt einzelne Zeilen der Datei und speichert sie in den Membern
    		Auftrag(const Auftrag &vorher, const Auftrag &nachher); // 2. Konstruktor, 
    		~Auftrag();
    
    		void readLine(string s); // Liest eine Zeile ein (wird von 1. Konstruktor aufgerufen)
    		operator== (const Auftrag &a); // Vergleicht ein Auftragselement mit einem zweiten übergebenen 
    };
    

    Die Auftragslistenklasse so:

    class Auftragsliste
    {
    	private:
    		vector<Auftrag*> auftraege;
    
    	public:
    		Auftragsliste(string filename); // 1. Konstruktor, liest Listen ein und schickt sie Richtung Auftrags-Klasse
    		Auftragsliste(); // 2. Konstruktor
    		~Auftragsliste();
    
    		void readFile(string filename); // wird durch den 1. Konstruktor aufgerufen
    		void compare(const Auftragsliste &vorher, const Auftragsliste &nachher); // wird aus 'main()' aufgerufen
    		void write(); // wird aus 'main()' aufgerufen
    };
    

    Bis jetzt habe ich die beiden Vektoren in einer geschachtelten for-Schleife verglichen. Wenn Filialnummer, Auftragsnummer und Auftragsdatum gleich sind, wird noch überprüft, ob der Name ungleich ist. Stimmt dies, werden beide miteinander verglichenen Aufträge in eine Datei geschrieben.

    Ich hoffe mal, es ist jetzt etwas verständlicher.
    Mit 'find()' kann man ja bloß einen "kompletten" Auftrag suchen, ich suche aber nur nach Übereinstimmung der obengenannten Variablen und nach NICHTÜBEREINSTIMMUNG des Namen.

    Dafür irgendwelche Ideen?

    Es funktioniert zwar alles, mein Problem ist nur die übertrieben lange Laufzeit bei mehr als 70.000 Elementen pro Vektor.


Anmelden zum Antworten