String zu enum



  • volkard schrieb:

    Die if-Abfragen sind wohl schneller bei den drei Werten. Aber je mehr Farben Du hast, desto langsamer werden sie. Irgenwann wird die map schneller, die ist nämlich beinahe unabhängig von der Anzahl der Werte. Aber hier würde ich nicht auf Geschwindigkeit achten. map klingt mir erstmal umständlicher.

    Damit der Geschwindigkeitsunterschied gegenüber dem IO-Flaschenhals überhaupt mal auffällt, brauchst du schon einige verschiedene Farben. Aber was genau ist denn an der map umständlicher?



  • Michael E. schrieb:

    Aber was genau ist denn an der map umständlicher?

    Nur das Initialisieren: Singleton oder lokale statische Variable und von einer Funktion füllen lassen, die diese map returnt und dabei pro Zugriff ein if bezahlen oder globale Variable vor der main() initialisieren lassen mit ebendieser Funktion und dann theoretisch die Initialisierungsreihenfolge globaler Objekte richtig steuern müssen. Aufwand, der es nicht wert ist, denke ich, weil man enum-Namen nicht in Dateien schreibt.



  • Dass man enum-Namen nicht in Dateien schreibt, sehe ich auch so. Aber die map-Variante finde ich schöner als Copy&Paste-if-Kaskaden (über switch könnte man reden).



  • switch geht aber nicht bei std::string. 😉



  • if ist hässlicher als map ist hässlicher als find.

    Warum kein statisches char*-Array mit std::find?



  • Michael E. schrieb:

    Dass man enum-Namen nicht in Dateien schreibt, sehe ich auch so. Aber die map-Variante finde ich schöner als Copy&Paste-if-Kaskaden (über switch könnte man reden).

    Aber perfektes hashing darf man auch nehmen.
    Ach, jetzt, wo ich auf Linux bin, gib's das ja als fertiges Paket. Mal installieren und ausprobieren…

    vhmain ~ # echo Red > in.txt
    vhmain ~ # echo Green >> in.txt
    vhmain ~ # echo Blue >> in.txt
    vhmain ~ # gperf in.txt
    
    /* C code produced by gperf version 3.0.4 */
    /* Command-line: gperf in.txt  */
    /* Computed positions: -k'' */
    
    #define TOTAL_KEYWORDS 3
    #define MIN_WORD_LENGTH 3
    #define MAX_WORD_LENGTH 5
    #define MIN_HASH_VALUE 3
    #define MAX_HASH_VALUE 5
    /* maximum key range = 3, duplicates = 0 */
    
    #ifdef __GNUC__
    __inline
    #else
    #ifdef __cplusplus
    inline
    #endif
    #endif
    /*ARGSUSED*/
    static unsigned int
    hash (str, len)
         register const char *str;
         register unsigned int len;
    {
      return len;
    }
    
    #ifdef __GNUC__
    __inline
    #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
    __attribute__ ((__gnu_inline__))
    #endif
    #endif
    const char *
    in_word_set (str, len)
         register const char *str;
         register unsigned int len;
    {
      static const char * wordlist[] =
        {
          "", "", "",
          "Red",
          "Blue",
          "Green"
        };
    
      if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
        {
          register int key = hash (str, len);
    
          if (key <= MAX_HASH_VALUE && key >= 0)
            {
              register const char *s = wordlist[key];
    
              if (*str == *s && !strcmp (str + 1, s + 1))
                return s;
            }
        }
      return 0;
    }
    

    Naja, nicht schön, aber die Idee sollte klar werden. Ich hätte den Anfangsbuchstaben genommen. Die Länge ist aber auch süß.



  • Darf man fragen wieso der Code in C ist?



  • Hacker schrieb:

    Darf man fragen wieso der Code in C ist?

    Ja. Und Du kannst es sogar ganz alleine herausfinden.



  • volkard schrieb:

    Hacker schrieb:

    Darf man fragen wieso der Code in C ist?

    Ja. Und Du kannst es sogar ganz alleine herausfinden.

    gperf, so so ...



  • volkard schrieb:

    Hacker schrieb:

    Darf man fragen wieso der Code in C ist?

    Ja. Und Du kannst es sogar ganz alleine herausfinden.

    Ich war unfähig es herauszufinden.

    % gperf -L C++ in.txt | xclip -o
    

    Das kopiert bei mir folgenden Code in die Zwischenablage:

    /* C++ code produced by gperf version 3.0.3 */
    /* Command-line: gperf -L C++ in.txt  */
    /* Computed positions: -k'' */
    
    #define TOTAL_KEYWORDS 3
    #define MIN_WORD_LENGTH 3
    #define MAX_WORD_LENGTH 5
    #define MIN_HASH_VALUE 3
    #define MAX_HASH_VALUE 5
    /* maximum key range = 3, duplicates = 0 */
    
    class Perfect_Hash
    {
    private:
      static inline unsigned int hash (const char *str, unsigned int len);
    public:
      static const char *in_word_set (const char *str, unsigned int len);
    };
    
    inline /*ARGSUSED*/
    unsigned int
    Perfect_Hash::hash (register const char *str, register unsigned int len)
    {
      return len;
    }
    
    const char *
    Perfect_Hash::in_word_set (register const char *str, register unsigned int len)
    {
      static const char * wordlist[] =
        {
          "", "", "",
          "Red",
          "Blue",
          "Green"
        };
    
      if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
        {
          register int key = hash (str, len);
    
          if (key <= MAX_HASH_VALUE && key >= 0)
            {
              register const char *s = wordlist[key];
    
              if (*str == *s && !strcmp (str + 1, s + 1))
                return s;
            }
        }
      return 0;
    }
    

    Warum da inline steht, es aber nicht direkt inline geschrieben ist, kann ich zwar nicht verstehen, aber ich sehe, dass da C++ und nicht C/C++ (wie bei volkard) generiert wurde.



  • Michael E. schrieb:

    Dass man enum-Namen nicht in Dateien schreibt, sehe ich auch so. Aber die map-Variante finde ich schöner als Copy&Paste-if-Kaskaden (über switch könnte man reden).

    Der Meinung bin ich auch, jedoch kann ich den Dateiinhalt leider nicht bestimmen. Ich habe jetzt die std::find Variante genommen, da sie schön schlank aussieht 🙂



  • gutefrage schrieb:

    Warum da inline steht, es aber nicht direkt inline geschrieben ist, kann ich zwar nicht verstehen, aber ich sehe, dass da C++ und nicht C/C++ (wie bei volkard) generiert wurde.

    Nö. Da wird immernoch C/C++ generiert - nur ein bisschen mehr Richtung C++ und nichtmehr ganz C-kompatibel. Macros sind mieser C++-Stil und register ist deprecated. Einmal "class" hinzuschreiben macht nicht wirklich C++ ohne "C/" draus 😛


Anmelden zum Antworten