Daten in Listen speichern...



  • Hallo,

    Wie siehts mit maps aus?

    MFG winexec*



  • Vielen Dank für den Gedankenanstoß.

    Hab mich jetzt mal ne Weile mit Maps etc. befasst.

    FÜr mich ergeben sich trotzalledem noch einige Fragen:

    1.) Welcher Container ist der Richtige?

    Anforderungen:
    - Auslesen einer Textdatei, in der Zeilenweise bis zur vier Daten stehen.
    - Speichern dieser Daten im Container.
    - Es sollen neue Datensätze in die Textdatei hinzugefügt werden, trotzdem wird die Menge der Datensätze nahezu konstant sein. Es handelt sich um ca. 40 Datensätze die maximal auf 60 erweitert werden.

    2.) Ich habe mir bereits mehrere Tutorials zu Maps durchgelesen und bereits selber versucht mir einen Map-Contaier zu basteln. Alle Tuts beschreiben jedoch nur Container mit der Speicherung von 2 Daten z.B.:

    typedef std::map<std::string,float> aktien;
        aktien *pAktien;
        aktien::iterator iter;
    
        pAktien = new aktien;
    
        (*pAktien)["VW"] = 12.f;
        (*pAktien)["Ford"] = 34.45f;
    

    Ich möchte aber vier Daten abspeichern. Also in etwa so:

    (*pAktien)["VW"] = "Volkswagen","KFZ",12.f;
        (*pAktien)["Ford"] = "Ford","LKW",34.45f;
    

    Wie mach ich sowas?

    3.) Ich möchte das ganze in einer Klasse definieren welche auch die Methoden zum Füllen und auslesen enthält? Habt ihr einen Ansatz 🙂

    Vielen Dank

    Oliver



  • Wenn Du mehrere Daten zusammen speichern willst mußt Du sie in einer Struktur oder Klasse zusammenfassen.



  • Hallo Jester und Co,

    kannst du das vielleicht noch etwas genauer ausführen? Würde mich sehr freuen, da mir noch die Erfahrung fehlt bzw ich zur Zeit voll auf dem Schlauch stehe 🙂

    Ich sehe immer nur Container wie z.B.:

    map<Key, Data, Compare, Alloc>
    

    Wie bekomm ich da jetzt mehrere Daten rein?
    Also hier nochmal mein Wunsch - eingentlich nix kompliziertes:
    <Container>
    <Key1> <Data> <Data> <Data>
    <Key1> <Data> <Data> <Data>
    </Container>

    Genauer: Ich suche nach einer Möglichkeiten, Information über chemische Elemente abzuspeichern.

    Als Key möchte ich die chem. Abkürzung (z.B. für Kupfer = Cu) speichern. Dazu soll dann noch der ausgeschriebene Name (Kupfer) sowie zwei weitere Eigenschaften im Contaiern gespeichert werden.

    Das alles soll in eine Klasse kommen und Methoden zum auslesen sowie ändern der Werte beinhalten.

    MIt fehlt echt der Ansatz. Obwohl ich seit Tagen Tutorials dazu lese...

    Bitte gebt mir nen Denkanstoß - am besten mit ein paar Fitzeln Code 🙂

    Vielen vielen Dank

    Oliver



  • Du mußt eine Struktur(oder Klasse) für Deine Daten anlegen:

    class MyData
    {
      string name;
      float wert;
      // ... was auch immer für Daten
    };
    
    std::map<std::string, MyData> dieMap;
    

    tut's dann.



  • Hallo

    um mal das nötigste zusammenzufassen

    class Element
    {
      ...
      std::string VollerName;
      std::string Abkuerzung;
      int Elektronen;
      int Protonen;
    }
    
    typedef std::map<std::string, Element> ElementMap; // Definition einer Map Abkürzung-Element
    typedef ElementMap::iterator ElementIt; // Definition für einen Iterator
    typedef ElementMap::value_type ElementVT; // Definition für den Wertetyp
    Element Neu = ...; // neues Element anlegen
    ElementMap Elemente; // Deklatration der Map
    Elemente.insert(ElementVT(Neu.Abkuerzung, Neu)); // Neues Element in Liste einfügen
    
    ElementIt it = Elemente.find("Cu"); // Element mit Abkürzung CU in der Liste suchen
    if (it == Elemente.end())
      // nicht gefunden
    else
      // gefunden
    

    bis bald
    akari[u]



  • Also erstmal vielen Dank Akari und Jester! 🙂

    Das hat mir super geholfen.
    Es hat aber auch zu neuen Problemen geführt bzw zu einem.

    Wie kann ich auf eine Methode einer in einer Map gespeicherten Klasse zugreifen.
    Diesen Satz als genaues Beispiel: 🙂

    class Element
    {
        private:
            string VollerName;
            string Abkuerzung;
            int Elektronen;
            int Protonen;
    
        public:
            // Methode getName
            string getName() {
                return VollerName;
            };
    };
    
    typedef map<string, Element> ElementMap; // Definition einer Map Abkürzung-Element
    typedef ElementMap::iterator ElementIt; // Definition für einen Iterator
    typedef ElementMap::value_type ElementVT; // Definition für den Wertetyp
    
    Element Neu = ...; // neues Element anlegen
    ElementMap Elemente; // Deklatration der Map
    Elemente.insert(ElementVT(Neu.Abkuerzung, Neu)); // Neues Element in Liste einfügen
    
    ElementIt it = Elemente.find("Cu"); // Element mit Abkürzung CU in der Liste suchen
    if (it == Elemente.end())
      // nicht gefunden
    else
      // gefunden
        // Diese folgende Zeile gibt einen Fehler aus! Warum???
        cout<< "Voller Name: " << Elemente["Cu"].getName <<endl;
        // genauso:
        cout<<"Voller Name: " << (*it).second.getName <<endl;
    

    Ich denke ich müsste einen Zeiger einbauen, meine Versuche sind aber gescheitert 😞
    Oder wo liegt der Fehler?

    Vielen Dank

    Oliver



  • Alles viel einfacher. Du hast die Klammern beim Funktionsaufruf vergessen. Folgende 3 Varianten sollten funktionieren:

    cout<< "Voller Name: " << Elemente["Cu"].getName() <<endl;
    cout<<"Voller Name: " << (*it).second.getName() <<endl;
    cout<<"Voller Name: " << it->second.getName() <<endl;
    

    Die beiden letzten Varianten sind dabei zu bevorzugen, da die erste nochmal sucht, was natürlich langsamer ist.

    Gib trotzdem bitte das nächste mal die Fehlermeldung mit dazu an. Oft hilft das.



  • Hallo,

    nochmal Danle für die Hilfe, bin jetzt nen ganzes Stück weiter.

    Folgendes "neues" Problem:

    Im Hauptprogramm befülle ich einen Kontainer mit Hilfe einer Klasse wie folgt:

    // Es wird die chemische Abkürzung, der Name des Elements und ein Preis gespeichert
    Elements elements;
    elements.addElement("Al","Aluminium",5.5f);
    elements.addElement("C","Carbon",7.7);
    elements.addElement("Fe","Eisen",999.99);
    elements.addElement("Ti","Titanium",50.0);
    

    Nun soll es einen Kontainer mit Materialien geben, welche sich jeweils zu gewissen Teilen aus den chemischen Elementen zusammensetzen.
    Dafür hab ich erstmal eine Klasse angelegt, welche in einem Kontainer die Zusammensetzung eines einzelnen Materials speichert:

    // Es wird die Abkürzung des chem. Elements und dessen Anteil an der
    // Zusammensetzunh gespeichert. (insgesamt natürlich immer 100%)
    MaterialComposition material1;
    material1.setComposition("Al",6.125);
    material1.setComposition("C",0.875);
    material1.setComposition("Fe",3.0);
    material1.setComposition("Ti",90.0);
    
    MaterialComposition material2;
    material2.setComposition("Al",30.0);
    material2.setComposition("C",10.0);
    material2.setComposition("Fe",55.0);
    material2.setComposition("Ti",5.0);
    

    Nun will ich diese Objekte alle in ein Kontainer einer Klasse Materials abspeichern.
    Soll dann in etwa so aussehen:

    // die oben def. Zusammensetzungen sollen alle in einen Kontainer
    Materials materials;
    materials.addMaterial(material1);
    materials.addMaterial(material2);
    

    Bei der Methode addMaterial hab ich aber noch Probleme:

    // Definition des Kontainers Materials
    typedef map<string, MaterialComposition> MaterialsMap;	// Definition einer Map Abkürzung-Element
    typedef MaterialsMap::iterator MaterialsIt;		// Definition für einen Iterator
    typedef MaterialsMap::value_type MaterialsVT;	// Definition für den Wertetyp
    
    class Materials
    {
    	private:
    		// Deklatration der Map
    		MaterialsMap MatMap;
    		string element_shortcut;
    	public:
    		// Methode zum Hinzufügen eines einzelnen Materials in den Kontainer
              // Wie übergebe ich die Objekte???? Was haben die für nen Typ???
    		void addMaterial(const objekt)
    		{
    			// Neues material in den Kontainer einfügen
    			MatMap.insert(objekt);
    		};
    
    };
    

    Geht sowas überhaupt, oder muss ich einen anderen weg gehen.

    Danke

    Oliver



  • Hey sieht gut aus.
    Wie hast Du MaterialComposition implementiert? (btw: chem. Verbindung heisst Compound)
    Du brauchst für die Element nen Container, und übergeben musst du ein Pair aus string und MaterialComposition.

    typedef map<string, MaterialComposition> MaterialsMap;
    typedef MaterialsMap::value_type Material;
    
    bool Materials::addMaterial(const Material& mat)
    {
        // Neues material in den Kontainer einfügen
        return MatMap.insert(mat).second;
            }; 
    // Main
    //...
    std::make_pair sugar = ( "Zucker", C6H12O6 );
    Materials materials;
    materials.addMaterial( sugar );
    


  • Moin,

    halb vier und ich bin auf ein neues Problem gestoßen 🙂

    Aber erstmal danke an den Chemie-Fan. Habs hinbekommen.

    In meinem Main Programm lade ich wie folgt Daten in die Kontainer:

    //Hauptprogramm
    int main()
    {
    	int operation;
    	bool again=true;
    	string element_shortcut,material_name;
    
    	Elements elements;
    	elements.addElement("Al","Aluminium",5.5f);
    	elements.addElement("C","Carbon",7.7);
    	elements.addElement("Fe","Eisen",999.99);
    	elements.addElement("Ti","Titanium",50.0);
    	elements.addElement("Ni","Nickel",0.9);
    
    	MaterialComposition material1("Ti64");
    	material1.setComposition("Al",6.125);
    	material1.setComposition("C",0.875);
    	material1.setComposition("Ti",90.0);
    	material1.setComposition("Fe",3.0);
    
    	MaterialComposition material2("Ti6242");
    	material2.setComposition("Fe",5.0);
    	material2.setComposition("Al",40.0);
    	material2.setComposition("Ti",55.0);
    
    	MaterialComposition material3("A286");
    	material3.setComposition("Al",0.5);
    	material3.setComposition("Ni",99.5);
    
    	Materials materials;
    	materials.addMaterial(make_pair(material1.getMaterialName(),material1));
    	materials.addMaterial(make_pair(material2.getMaterialName(),material2));
    	materials.addMaterial(make_pair(material3.getMaterialName(),material3));
    

    Die Klasse Elements verfügt über eine Methode, die Daten des Kontainers ElementsMap in einer Art Tabelle augibt.

    Rufe ich diese Methode mit

    elements.listElements();
    

    aus dem Main direkt auf, wird alles ordnungsgemäß angezeigt. Eine weitere Funktion (getElementsSize) dieser Klasse liefert mir die Anzahl der gespeicherten Werte im Kontainer.

    Jetzt passiert aber folgendes:
    Rufe ich diese Methode aus einer anderen Klasse auf, wird mir gesagt, der Kontainer sei leer.
    z.B.:
    die Klasse Materials verfügt auch über eine Methode (listMaterials) welche alle Materialien tabellarisch darstellt. Diese verweisst jedoch wieder auf die Methode zur Darstellung der einzelnen Elemente.
    Im Main Programm steht also nur:

    materials.listMaterials();
    

    In der Klasse Materials steht:

    class Materials
    {
        ...
        void listMaterials()
        {
            ...
            (*iter).second.listElements();
        };
    };
    

    Mach ich es so, ist der Kontainer leer und bei mir gehts net weiter 😞

    Bitte um Ideen... Danke

    Geh jetzt pennen... Gute nacht!


Anmelden zum Antworten