Strings zu einer ID umwandeln



  • Hi,
    ich muss aus mehreren Strings eine einmalige ID Nr. erstellen die ich dann auch verwenden kann um zu überprüfen ob es schon einen Eintrag mit der selben ID giebt.

    Also ich habe mir das so vorgestellt:

    string string1 = "hallo";
    string string2 = "blubb"
    string string3 = "ka";
    string ....
    string fstring;

    fsting = string1 + string2 + string3 + ....

    und jetzt den fstring in eine ID umwandeln, die ihn Einmalig macht ausser man wuerde natuerlich noch einmal die selben Daten für string1, 2, 3 usw. eingeben.

    Habe erst gedacht ich zähle einfach die Anzahl der Buchstaben in fstring, dachte mir aber dann, dass dies zu ungenau sei. Mir faellt nichts ein bzw. weiß net wie ich es realisieren soll, dass am Ende der fstring in eine einmalige Zahl umgewandelt wird.

    vllt. die Bitgröße berechnen, habe ich aber ka wie.

    Hoffe mir kann da jemand helfen

    Rgds
    Coda



  • Das Zauberwort heißt "Hash". Beispielsweise MD5.



  • Von Zauberei lässt man sich leicht täuschen: Hash-Funktionen liefern nur nahezu eindeutige Werte.

    Wirklich eineindeutige Werte bekommt man nur durch eine bijektive Abbildung.
    ZB. kann man diese in einer std::mapstd::string,int speichern: Wenn ein String schon in der Map existiert, wird seine ID zurückgegeben, sonst wird eine neue ID erzeugt (letzte ID +1), der String mit dieser hinzugefügt und die ID zurückgegeben.



  • class foo
    {
        std::map<std::string, std::size_t> m_fstring;
        void push_back(std::string const& str) { static std::size_t id(0); m_fstring.insert(std::make_pair(str, id++)); }
    
    public:
        std::size_t get_id(std::string const& str) const
        { 
            std::map<std::size_t, std::string>::const_iterator it(m_fstring.find(str));
            return it != m_fstring.end() ? (*it).first : (push_back(str), get_id(str));
        }
    };
    

    so ... damit kannst du das ganz einfach so nutzen:

    int main()
    {
        foo inst;
        std::cout << inst.get_id("Das ist ein String") << std::endl;
        std::cout << inst.get_id("Das ist ein String") << std::endl;
        std::cout << inst.get_id("Das ist ein anderer String") << std::endl;
    }
    

    => Dem String wird eine eindeutige ID zugewiesen.



  • Ich würde die Elemente der Map vertauschen:

    std::map<std::string, std::size_t>
    

    Dann ist die Suche nach dem Namen nämlich effizienter (O(log N) stat O(N)), denn dafür soll ja eine Map verwendet werden!



  • Danke, dass sieht schon mal ganz gut aus, ich werde es mal probieren.

    Rgds
    Coda


Anmelden zum Antworten