list, map, vector, array, ... oder string?



  • hi,
    list, vector, map, array, set .. sind alles container, wo ich objekte speichern kann.
    ich habe folgendes problem: ich habe ca. 500 strings (benutzernamen), die in einem solchen container gespeichert werden sollen - welcher bietet sich da an?
    der nutzer gibt seinen namen ein, wenn es ihn schon gibt, dann wird der entsprechende nutzername im bildschirm angezeigt, wenn es den namen noch nicht gibt, dann wird ein neuer "angelegt" (also zu meinem container hinzugefügt).

    vector wäre perfekt, weil ich einfach vector.push_back() machen kann, wenn ein neuer name hinzugefügt wird. aber ich kann, falls es den namen schon gibt, diesen nicht einfach finden (vector.find gibt es ja nicht..).

    map wäre da besser, weil ich einfach map["benutzername"] machen kann zum hinzufügen und map.find("benutzername") gibt es auch, aber ich brauche ja einen zweiten wert (fällt mir gerade ein: map<string,void> geht nicht, oder?) - außerdem habe ich bei dieser lösung das gefühl, dass ich den sinn von map völlig zweckentfremde...

    list, set, ... habe ich noch nie benutzt, aber der cplusplus referenz nach klingen die nicht schlecht - allerdings liefert list z.b auch kein list.find() .. 😕 (eigentlich doch unsinnig, oder? ist doch logisch, dass man in einer liste mal was suchen muss, oder?)

    meine letzte option wäre einfach einen riesigen string zu basteln und diesen dann mit string.find nach den benutzernamen suchen lassen, aber ob das optimal ist?

    natürlich könnte ich selber eine methode basteln, die bspws. meinen vector<string> durchsucht:

    bool vector_find(vector<string> t, string keyword)
    {
    for(vector<string>::iterator it = t.begin(); it != t.end(); ++t)
    {
    if(*it == keyword)
    return true;
    else
    return false;
    }
    }
    

    ich hoffe auf konstruktive hinweise, mfg 🙂



  • std::map<std::string, void> -> std::setstd::string
    map["benutzername"] -> set.insert("benutzername")
    map.find("benutzername") -> set.find("benutzername")

    Ansonsten hilft auch: http://stackoverflow.com/questions/471432/in-which-scenario-do-i-use-a-particular-stl-container

    Edit:
    vector_find(vector<string> t, string keyword) -> std::find(t.begin(), t.end(), keyword)


  • Mod

    Die Frage ist: Was willst du damit machen? Für das Suchen bestimmter Einträge sind assoziative Container (multi/unordered-set/map) besser, sofern du nicht anfangen möchtest, selber spezielle Containeradaptoren zu schreiben. Jedoch: 500 strings sind so gut wie nichts. Da geht selbst das Suchen in einem unsortierten Sequenzcontainer (vector, deque, list). Wenn du auch noch was anderes außer Suchen und Einfügen machen möchtest, sind diese daher eventuell besser.

    Aber generell: Bei 500 Einträgen kannst du nichts falsch machen, aber das heißt ja nicht, dass man nicht trotzdem versuchen kann, es optimal zu lösen. Siehe Nathans Link, wobei ich diesen hier allerdings besser finde:
    http://stackoverflow.com/questions/10699265/how-can-i-efficiently-select-a-standard-library-container-in-c11

    Wenn wir annehmen, dass du irgendwann mal eine Milliarde Zeichenketten durchsuchen möchtest, dann bietet sich ein unordered_set/unordered_multi_set an, sofern man bei den Mitteln der Standardbibliothek bleiben möchte. Oder falls dein Compiler kein C++11 kann, lässt du eben das unordered weg (oder besser: besorgst dir einen aktuellen Compiler).



  • vector.find schrieb:

    allerdings liefert list z.b auch kein list.find() .. 😕 (eigentlich doch unsinnig, oder? ist doch logisch, dass man in einer liste mal was suchen muss, oder?)

    Nein, das ist schon sinnvoll. Container bieten neben allgemeinen Methoden wie begin() , end() , size() die Operationen als Memberfunktionen an, für die sie spezialisiert sind. Der Rest kann über globale Funktionen implementiert werden, so hat man keine unnötige Codeduplikation.

    In dem Fall ist der STL-Algorithmus std::find() deine Wahl, wenn es um lineare Suche geht. Da assoziative Container binäre Suche ermöglichen, haben sie eine spezialisierte find() -Methode.

    Als Container für deinen Fall bietet sich std::set an. Wenn du hauptsächlich einfügst und suchst, bist du damit schon recht gut beraten.


Anmelden zum Antworten