unordered_map



  • hi,

    wie kann ich folgendes ohne undefined behavior implementieren?
    ich moechte die key/val pairs der hashtable ausgeben und zugleich iterativ die elemente loeschen...

    // unordered_map::erase
    #include <iostream>
    #include <string>
    #include <unordered_map>
    
    int main ()
    {
      std::unordered_map<std::string,std::string> mymap;
    
      // populating container:
      mymap["U.S."] = "Washington";
      mymap["U.K."] = "London";
      mymap["France"] = "Paris";
      mymap["Russia"] = "Moscow";
      mymap["China"] = "Beijing";
      mymap["Germany"] = "Berlin";
      mymap["Japan"] = "Tokyo";
    
      // erase examples:
      //mymap.erase ( mymap.begin() );      // erasing by iterator
      //mymap.erase ("France");             // erasing by key
      //mymap.erase ( mymap.find("China"), mymap.end() ); // erasing by range
    
      // show content:
      for ( auto& x: mymap ) {
        std::cout << x.first << ": " << x.second << std::endl;
        mymap.erase(x.first);
      }
    
      return 0;
    }
    


  • ich nehme an das ist nur so moeglich?

    while ( !mymap.empty() ) {
      	auto x = mymap.begin();
        std::cout << x->first << ": " << x->second << std::endl;
        mymap.erase(x->first);
      }
    


  • Dein Beispiel ist sehr verkürzt.
    Das ist zwar eigentlich gut, aber mir ist nicht ganz klar, was genau du brauchst.
    Deshalb schmeiss ich mal den Vorschlag in den Raum:

    remove_if mit Lamda, was immer true zurück gibt und die Ausgabe macht.



  • Ich denke du suchst sowas hier:

    for (auto iter = mymap.begin(); iter != mymap.end(); )
    {
        std::cout << iter->first << ": " << iter->second << std::endl;
    
        if (removeBedingung)
            iter = mymap.erase(iter);
        else    
            ++iter;
    }
    

    unordered_map::erase(iter) gibt einen Iterator auf den Nachfolger des gelöschten Elements zurück, mit dessen Hilfe man obiges Pattern umsetzen kann.

    Gruss,
    Finnegan



  • das konzept ist wie folgt:
    ich such nach den top 10 visited urls....die urls stehen in einem logfile (5GB)

    - ich zaehle urls und fuege diese dafür in eine hashtable ein (unordered_map<string, unsigned int>)
    - dann erstelle ich einen min heap, welcher die top 10 visited urls beinhalten soll...



  • Statt min heap bietet sich partial_sort an. Und es sagt auch keiner, dass Du bei der Iteration gleich die Elemente löschen musst. Das ginge ja auch so:

    vector<string, size_t> map2vec(unordered_map<string, size_t> const& map) {
        vector<pair<string, size_t>> result;
        result.reserve(map.size());
        for (auto& p: map) {
            result.push_back(p);
        }
        return result;
    }
    

    (ungetestete Skizze)

    Idealerweise könnte man auch die URL Strings von der map in einen vector umziehen lassen. Die Map lässt sich aber, soweit ich das sehen kann, die Schlüssel da nicht rausmoven. Ich wüsste jedenfalls nicht wie. In Rust wär das jetzt schön einfach:

    let v: Vec<_> = mymap.into_iter().collect();
    


  • ja, aber sagen wir es stehen 1mill elemente in der map und ich brauche die top 1k urls... speicher optimieren und das element von der map in den heap einfuegen, danach den map key loeschen...


Anmelden zum Antworten