Map mit Listen



  • Hallo,

    ich möchte in einem "Map" neben "Int" Schlüsseln "list" bzw. "vector" Werte speichern. Ich suche eine Möglichkeit nachträglich listenelemente zu einem exitierenden Schlüssel einzutragen. Im folgende Code habe ich das versucht, nur werden durch "cout" nur die ersten zwei Elemente ausgegeben. Wie kann man das hinbekommen?

    #include <iostream>
    #include <string>
    #include <list>
    #include <map>
    #include <utility>
    
    using namespace std;
    
    int main () {
    
        list<int> Liste;
        map<int, list<int> > myMap;
    
        Liste.push_back(11);
        Liste.push_back(22);
    
        myMap.insert(pair<int, list<int> >(42, Liste));
    
        Liste.push_back(33);
        Liste.push_back(44);
        Liste.push_back(55);
    
        for(list<int>::iterator it= myMap[42].begin(); it != myMap[42].end(); it++) 
            cout << *itera << endl;
    
    return 0;
    }
    

    Danke für Hilfe!

    Jo



  • Hallo,

    Beim insert wird die Liste kopiert. Die Liste in der map weiß also nichts von den neu hinzugefügten Elementen. Du mußt die Liste in der map ansprechen.

    myMap[42].push_back(33);
        myMap[42].push_back(44);
        myMap[42].push_back(55);
    


  • Hallo,

    in dem Moment, wo du die Liste in die Map packst, wird von der Liste eine Kopie angefertigt. Die Kopie wird in die Map getan.

    Du arbeitest da also mit einer anderen Liste weiter, nicht mit der, die in der Map ist.

    Eine Lösung ist, Zeiger auf Listen zu verwenden:

    std::map<int, std::list<int>*> myMap;
    
    std::list<int>* p_list = new std::list<int>;
    
    p_list->push_back(11);
    p_list->push_back(22);
    
    myMap[42] = p_list;
    
    p_list->push_back(33);
    p_list->push_back(44);
    p_list->push_back(55);
    
    // usw.
    

    Da musst du nur nachher aufpassen, dass du die Listen auch mit delete wieder löschst!



  • Danke soweit! Aber wie sieht dann die ausgabe aus?

    so nicht?!

    for(list<int>*::iterator it = myMap[42].begin(); it != myMap[42].end(); it++)
    cout << *it << endl;



  • NoPanic2007 schrieb:

    list<int>*::iterator

    Was soll das denn sein?
    Der Stern gehört da ja nun wirklich nicht hin!

    Das geht dann natürlich so:

    for(list<int>::iterator it = myMap[42]->begin(); it != myMap[42]->end(); it++)
    {
        cout << *it << endl;
    }
    


  • #include <iostream>
    #include <list>
    #include <map>
    #include <utility>
    #include <iterator>
    #include <algorithm>
    
    int main () 
    {
    
        std::list<int> list;
        std::map<std::size_t, std::list<int> > map;
        map.insert(std::make_pair(42, list));
        for (std::size_t i = 0; i < 10; ++i)
            map[42].push_back(i * 10 + i);
    
       std::copy(map[42].begin(), map[42].end(), std::ostream_iterator<int>(std::cout, " "));
    }
    

    ...



  • Was macht den map[42] genau? sucht das immer in der map nach nem key 42?
    Dann wäre das aber sehr langsam

    for (std::size_t i = 0; i < 10; ++i)
            map[42].push_back(i * 10 + i);
    


  • Das sieht gut aus!!! Danke



  • Was macht den map[42] genau? sucht das immer in der map nach nem key 42?
    Dann wäre das aber sehr langsam

    oO dann mach halt

    std::map<std::size_t, std::list<int> >::iterator it = map.begin() + 42;
    (*it).push_back(11);
    


  • Das wird wohl nicht gehen. map hat schließlich keine random access iteratoren

    std::map<std::size_t, std::list<int> >::iterator it = map.find(42);
    


  • Wenn man das Ganze dynamisch machen möchte, wie sieht das dann aus?

    #include <iostream>
    #include <list>
    #include <map>
    #include <utility>
    #include <iterator>
    #include <algorithm>
    
    int main () 
    {
    
        std::list<int> list;
        typedef std::map<std::size_t, std::list<int> > myMap;
        myMap* map;
    
        map->insert(std::make_pair(42, list));
        for (std::size_t i = 0; i < 10; ++i)
            map[42].->(??????)push_back(i * 10 + i);
    
    }
    


  • myMap* map;
        map = new myMap; //nicht vergessen
        map->insert(std::make_pair(42, list));
        for (std::size_t i = 0; i < 10; ++i)
            (*map)[42].push_back(i * 10 + i);
    


  • dabei ist eine std::map schon ein dynamischer Container?! Was solln das ?!



  • Das ist natürlich die Frage. 🙂
    Man sollte dynamische Speicherverwaltung nur anwenden, wenn man sie unbedingt braucht.



  • Kann das mal jemand erläutern!?

    Wenn ich delete map; mache, bin ich dann auf der sicheren Seite? Oder wird da irgendwas nicht abgeräumt?



  • Ja klar bist du dann auf der sichern Seite (was immer das sein mag). Wir verstehen hier nur nicht, warum du unbedingt eine map dynamisch erstellen willst. Das macht hier einfach keinen Sinn.



  • das ganze soll in ein grösseres programm eingegliedert werden und nur eventuell benutzt werden...



  • Noch mal. Warum willst du eine map dynamisch erstellen? Was genau brauchst du was du nicht mit Referenzen machen kannst?



  • NoPanic2007 schrieb:

    das ganze soll in ein grösseres programm eingegliedert werden und nur eventuell benutzt werden...

    (Ich setze mal voraus, dass es Dir um "Speicherplatzminimierung" geht)
    map verwaltet seine Elemente sowieso schon dynamisch (ist IIRC zwar nicht vorgeschrieben aber gängige Praxis) und sein "Verwaltungsteil" ist nicht besonders groß - da "spart" man am falschen Ende, wenn man die Map selbst per new allozierst.
    Du kannst ja mal mit einem "sizeof()" nachsehen, wie viel Speicherplatz die map verwendet - ich bin sicher: Ist zu vernachlässigen.
    Gleichzeitig kaufst Du Dir aber Probleme mit der dynamischen Speicherverwaltung ein (new ist sehr "laufzeitfressend", Verwaltung von new/delete ist aufwendig, Code wird durch Verwendung von "->"bzw. "*." unübersichtlich, ....), die es nicht wert sind.

    Gruß,

    Simon2.



  • Okay, verstehe! Merci. 👍


Anmelden zum Antworten