konstantes Array aus Strukturen



  • Hallo,
    das mit den Maps funktioniert soweit auch ganz gut.

    Es ist eigentlich ziemlich simpel und ich denke, ich werde das vorerst so lassen.

    std::map<std::string, int> myColorMap;

    Eine Frage habe ich noch, welche Exception wird geworfen, wenn die Map den String nicht finden kann.

    Ich würde das gerne mit try und catch abfangen.

    Die c++ Reference schreibt etwas von einem Iterator, was mich nicht direkt weiterbringt.

    EDIT: Habe gerade herausgefunden, dass überhaupt keine Exception geworfen wird..
    Naja, erstmal weiter googlen und hoffen, dass hier noch eine einfache Antwort kommt 😞

    EDIT 2:
    habe mir jetzt so einen Code zusammengebastelt:

    Kann man das so durchgehen lassen?

    // This is just for test issues
    		std::string string =  "pfgurple";
    
    		if(myColorMap.find(string) != myColorMap.end() )
    			cout << "black ==> " << myColorMap.find(string)->second << endl;
    		else
    			cout << "ColorString was not found in colorMap" << endl;
    


  • Warum wurde der Link zum Buch immer noch von keinem Mod entfernt? So wird er nur weiter dupliziert (schon 4 Posts mittlerweile)...


  • Mod

    zerärgert schrieb:

    Warum wurde der Link zum Buch immer noch von keinem Mod entfernt? So wird er nur weiter dupliziert (schon 4 Posts mittlerweile)...

    Immer mit der Ruhe, ein alter Mann ist kein D-Zug Wikipedia-Löschadmin.

    Der Offtopicteil und alle Links zweifelhafter Legalität sollten nun vollständig entfernt sein.



  • Phys1k3r schrieb:

    EDIT 2:
    habe mir jetzt so einen Code zusammengebastelt:

    Kann man das so durchgehen lassen?

    // This is just for test issues
    		std::string string =  "pfgurple";
    
    		if(myColorMap.find(string) != myColorMap.end() )
    			cout << "black ==> " << myColorMap.find(string)->second << endl;
    		else
    			cout << "ColorString was not found in colorMap" << endl;
    

    Ja, das geht wunderbar. Allerdings ist es ein kleines bisschen ineffizient, weil du zwei mal den selben String suchst, den du doch schon beim ersten mal gefunden hast, mach es in Zukunft lieber so:

    std::map<char const*, myColor>::const_iterator iter = myColorMap.find(string); ///Tja, hättest du einen C++11-kompatiblen Compiler, könntest du einfach auto benutzen :p
    if(iter != myColorMap.end() )
            cout << "black ==> " << iter->second << endl;
    else
            //..
    


  • SeppJ schrieb:

    zerärgert schrieb:

    Warum wurde der Link zum Buch immer noch von keinem Mod entfernt? So wird er nur weiter dupliziert (schon 4 Posts mittlerweile)...

    Immer mit der Ruhe, ein alter Mann ist kein D-Zug Wikipedia-Löschadmin.

    ???
    Ich dachte du bist 30?


  • Mod

    Sone schrieb:

    SeppJ schrieb:

    zerärgert schrieb:

    Warum wurde der Link zum Buch immer noch von keinem Mod entfernt? So wird er nur weiter dupliziert (schon 4 Posts mittlerweile)...

    Immer mit der Ruhe, ein alter Mann ist kein D-Zug Wikipedia-Löschadmin.

    ???
    Ich dachte du bist 30?

    Werd mal 30 und dann beurteile das nochmal 🙂



  • SeppJ schrieb:

    Sone schrieb:

    SeppJ schrieb:

    zerärgert schrieb:

    Warum wurde der Link zum Buch immer noch von keinem Mod entfernt? So wird er nur weiter dupliziert (schon 4 Posts mittlerweile)...

    Immer mit der Ruhe, ein alter Mann ist kein D-Zug Wikipedia-Löschadmin.

    ???
    Ich dachte du bist 30?

    Werd mal 30 und dann beurteile das nochmal 🙂

    Ich weiß nicht, ob du mir jetzt Leid tun sollst 🙂 😃



  • Phys1k3r schrieb:

    Die c++ Reference schreibt etwas von einem Iterator, was mich nicht direkt weiterbringt.

    Tja, dass dich das nicht weiterbringt liegt am verkorksten Design von C++ map.
    Es ist wirklich sinnfrei, einen Iterator zum Suchen nach dem unique(!) Key einer Map zu missbrauchen. Ein Iterator ist zum Iterieren da, kann aber bei Sucherfolg hier nicht weiter iterieren, da der Key ja unique ist.
    Vernünftige Sprachen bieten deshalb für solcherlei simpler Basisfunktionalität entsprechende eigene Konstrukte an (also ohne Umweg über Iteratoren), und haben auch gar nicht erst solchen C++ Nonsens wie multimap (wo der Iterator evtl. sinnvoll einzusetzen wäre) oder gar multiset (ein Widerspruch in sich).



  • Wutz schrieb:

    Tja, dass dich das nicht weiterbringt liegt am verkorksten Design von C++ map.

    Ne. Das liegt daran, dass er die STL nicht kennt. Exceptions sind fuer unerwartete Ausnahmefaelle da. Dass das Element nicht vorhanden ist, ist wohl erwartet, oder?

    Wutz schrieb:

    Es ist wirklich sinnfrei, einen Iterator zum Suchen nach dem unique(!) Key einer Map zu missbrauchen.

    Es ist wirklich sinnfrei, Speicherplatz auf dem c-plusplus.net-Server fuer deinen Post zu missbrauchen. :p

    Wutz schrieb:

    Ein Iterator ist zum Iterieren da, kann aber bei Sucherfolg hier nicht weiter iterieren, da der Key ja unique ist.

    Klar kannst du mit einem Iterator "weiteriterieren". Und was du mit "da der Key ja unique ist" meinst, ist mir gaenzlich ein Raetsel.

    Wutz schrieb:

    Vernünftige Sprachen bieten deshalb für solcherlei simpler Basisfunktionalität entsprechende eigene Konstrukte an (also ohne Umweg über Iteratoren)

    Dann zeig mir doch mal diese eigenen Konstrukte. Und bitte komm mir jetzt nicht mit Java/C#.

    Wutz schrieb:

    , und haben auch gar nicht erst solchen C++ Nonsens wie multimap (wo der Iterator evtl. sinnvoll einzusetzen wäre)

    Nonsens? 😃
    Weil du keinen Anwendungsfall kennst, ist multimap also Nonsesns, hab ich das richtig verstanden? :p

    Wutz schrieb:

    oder gar multiset (ein Widerspruch in sich).

    Weil?



  • Kellerautomat schrieb:

    Und was du mit "da der Key ja unique ist" meinst, ist mir gaenzlich ein Raetsel.

    oder gar multiset (ein Widerspruch in sich).
    Weil?

    Weil du keine Ahnung hast, wovon du redest. map/set sind grundlegende Datenstrukturen, und zu solchen grundlegenden Datenstrukturen gehören elementare Funktionalitäten in einen Standard, aber das kannst du mit deinem zusammengegoogelten Halbwissen natürlich nicht wissen und versuchst es, mit naiver Dummdreistigkeit zuzudecken.



  • Sag doch einfach mal konkret, was dir fehlt, dann kann man darueber diskutieren. Dieses duemmliche gebrabbel bringt niemanden weiter.



  • Wutz schrieb:

    Tja, dass dich das nicht weiterbringt liegt am verkorksten Design von C++ map.

    du sprichst wahrscheinlich auf das fehlen einer direkten Existenzfunktion an. Aber das ist in den meisten Fällen bei einer map nicht das, was man will. In den allermeisten Fällen will man ja nicht nur wissen, ob das Element mit dem Schlüssel existiert, sondern das Element, bzw den damit assoziierten Wert, in dem Fall auch gleich haben. Semantishc hätte ich eine solche Existenzfunktion bei dem Set erwartet, kann aber auch aus der Sichtweise des Sets als Schlüssel-Wertpaar mit intrinsischen Schlüssel damit leben, dass die Funktion nicht existiert.

    Es ist wirklich sinnfrei, einen Iterator zum Suchen nach dem unique(!) Key einer Map zu missbrauchen.

    Ich möchte ja nicht immer nur den einen Schlüssel haben, sondern über eine Untermenge iterieren können, die durch zwei Schlüssel definiert ist. Anwendungen dafür gibt es zu hauf.

    und haben auch gar nicht erst solchen C++ Nonsens wie multimap (wo der Iterator evtl. sinnvoll einzusetzen wäre) oder gar multiset (ein Widerspruch in sich).

    Warum sollten Multisets ein Widerspruch in sich sein? Den Begriff gibt es in der Mathematik seit dne 70er Jahren, das Konzept ist auch bekannt als bag:
    http://en.wikipedia.org/wiki/Multiset
    Zudem verweis eich erneut auf das set/multiset als Map für intrinsische Schlüssel-Wertpaare.

    Ich fürchte, da verrennst du dich gerade etwas.



  • otze schrieb:

    du sprichst wahrscheinlich auf das fehlen einer direkten Existenzfunktion an. Aber das ist in den meisten Fällen bei einer map nicht das, was man will.

    Das ist aber die originale Frage hier gewesen.

    otze schrieb:

    In den allermeisten Fällen will man ja nicht nur wissen, ob das Element mit dem Schlüssel existiert, sondern das Element, bzw den damit assoziierten Wert, in dem Fall auch gleich haben.

    Natürlich. Aber auch das kann die std::map (erst recht) nicht leisten. Nichts anderes habe ich gesagt, als ich von Basis/Elementarfunktionalitäten die in einen Standard gehören sprach.

    otze schrieb:

    Semantishc hätte ich eine solche Existenzfunktion bei dem Set erwartet,

    Die Key-Folge einer map ist immer ein Set, aber auch beim Set gibts diese Elementarfunktion nicht, stattdessen muss man ein neues Objekt(!) Iterator bzw. bei equal_range sogar ein Paar Iteratoren neu definieren, nur um festzustellen, ob eine map/set einen unique Key nun enthält oder nicht, wobei das equal_range-it-Pair auch wieder redundant ist, da wegen des unique keys einer map der range immer gleich 1 ist. Das ist Sinnfreiheit pur, fehleranfällig und per se inperformant.
    Ganz schlimm sieht es bei key_comp aus, mit dem man auch nach einem Key suchen kann; nachdem man mühsam ein neues Objekt hierfür erzeugen muss, kann man von dem noch nicht mal mehr auf den value referenzieren und muss doch wieder auf die map rückbeziehen.

    otze schrieb:

    Ich möchte ja nicht immer nur den einen Schlüssel haben, sondern über eine Untermenge iterieren können, die durch zwei Schlüssel definiert ist.

    Nicht immer, aber meistens, siehe deine eigene Argumentation oben, zumal dieses Iterieren zwischen 2 Keys eine Sortierung dieser voraussetzt, und diese ständig aktuell zu halten, ist wiederum per se inperformant weil überhaupt nicht nötig für die Standardanwendungsfälle einer map/set. (die Key-Indizierung passiert meistens über Hashes und die sind nunmal üblicherweise nicht so sortiert wie ihre Basiswerte, d.h. um die definierte std::map Sortierung sicherzustellen, muss jedesmal (bei jedem Update in der map) die komplette Key-Folge durchsortiert werden).
    Die verschämt mit TR1 nachgereichten unordered_map/set zeigen wie es gehen kann, sind aber bekanntlich eben nicht C++98 und somit nicht überall verfügbar.


  • Mod

    Wutz schrieb:

    Die Key-Folge einer map ist immer ein Set, aber auch beim Set gibts diese Elementarfunktion nicht, stattdessen muss man ein neues Objekt(!) Iterator bzw. bei equal_range sogar ein Paar Iteratoren neu definieren, nur um festzustellen, ob eine map/set einen unique Key nun enthält oder nicht, wobei das equal_range-it-Pair auch wieder redundant ist, da wegen des unique keys einer map der range immer gleich 1 ist. Das ist Sinnfreiheit pur, fehleranfällig und per se inperformant.

    Das ist nur dann inperformant, wenn es eine Methode gibt, sets/maps zu durchsuchen, ohne einen Iterator (oder etwas äquivalentes) zu verwenden. Ich kann mir keine Implementation vorstellen, bei der das der Fall wäre.
    Abgesehen davon hindert dich ja nichts, eine contains-Funktionalität nachzurüsten.



  • Wutz schrieb:

    Das ist aber die originale Frage hier gewesen.

    Nein? Die Originale Frage war, dass der User zu einem String einen int wert haben wollte. Und das ist nicht die Frage nach der Existenz. Unter der Bedingung, dass die Datei validiert ist, ist die Existenzfrage sogar völlig egal und du schreibst:

    map<string,int> mymap;
    //...
    int color=mymap[mycolorstring];
    

    Und ansonstne benutzt du map::find. Das leistet sowohl die Existenz als auch die Übergabe des Wertes.

    Die Key-Folge einer map ist immer ein Set, aber auch beim Set gibts diese Elementarfunktion nicht, stattdessen muss man ein neues Objekt(!) Iterator bzw. bei equal_range sogar ein Paar Iteratoren neu definieren, nur um festzustellen, ob eine map/set einen unique Key nun enthält oder nicht, wobei das equal_range-it-Pair auch wieder redundant ist, da wegen des unique keys einer map der range immer gleich 1 ist. Das ist Sinnfreiheit pur, fehleranfällig und per se inperformant.

    1. Ich fürchte dass ein Aufruf von map::end() und operator == exakt gar nichts kostet.
    2. Du solltest im Release Modus compilieren.
    3. equal_range verwendest du nur im generischen Kontext, wenn du auch eine multimap/ ein multiset erwarten würdest. Der Standard hat sich hier in allen Fällen für ein generisches Interface entschieden, in dem man den einen Typ gegen den anderen leicht austauschen kann. Kannst du als schlechtes Design sehen, aber du kannst mit multimaps eh nichts anfangen.

    Ganz schlimm sieht es bei key_comp aus, mit dem man auch nach einem Key suchen kann;

    Du hast die map nicht verstanden. key_comp legt fest, wie die Schlüssel verglichen werden um den RB-Baum aufzubauen. Das ist genau dann sinnvoll, wenn es keinen operator< gibt den die Map verwenden kann, oder wenn man eine bestimmte Sortierung zum iterieren braucht. Die Methode key_comp ist nur dazu da, dass selbst bestimmte Schlüssel miteinander verglichen werden können.

    (die Key-Indizierung passiert meistens über Hashes und die sind nunmal üblicherweise nicht so sortiert wie ihre Basiswerte, d.h. um die definierte std::map Sortierung sicherzustellen, muss jedesmal (bei jedem Update in der map) die komplette Key-Folge durchsortiert werden).
    Die verschämt mit TR1 nachgereichten unordered_map/set zeigen wie es gehen kann, sind aber bekanntlich eben nicht C++98 und somit nicht überall verfügbar.

    1. Du hast RB-Bäume nicht verstanden.
    2. Du hast hashmaps nicht verstanden.
    Irgendwann hat dir wohl mal jemand gesagt, dass hashmaps voll cool sind, hat dir aber verschwiegen, dass die auch durchaus eine ganze Latte von Nachteilen haben. Zum Beispiel kann das einfügen von n Elementen in eine Hashmap in O(n^2) liegen - und Lookup in O(n). Bei der map ist es garantiert in O(n log(n)), bzw log(n), trotz "Sortierung der Keyfolge" (was im Normalfall nur das Umhängen von ein paar Zeigern ist). Es gibt sogar sehr effektive Angriffe auf Webserver, die das ausnutzen.


Anmelden zum Antworten