std::map find



  • gibts ne möglichkeit in ner stringmap anstatt nach einem exakten match nach dem besten match zu suchen?

    Eingabe: abc

    ab
    abcdef <---- der da 😉
    xyz



  • Hallo

    Nein das kann std::map nicht. Dazu brauchst du einen eigenen Container, bzw. einen vector mit einer entsprechenden manuellen Suche.

    bis bald
    akari



  • hmm schreib dir erstmal die Funktion mit der danach suchen willst. Das dann in einen entsprechenden Container mit reinzubauen, ist nicht so sonderlich schwer.



  • Es gibt eine Möglichkeit, das mit std::map zu realisieren. Dazu musst du als dritten Template-Parameter einen anderen Comparator einsetzen:

    class my_comparator
    {
     public:
      bool operator() (const std::string& s1, const std::string& s2) const
      {
        //vergleiche s1 und s2 irgendwie
      }
    };
    
    std::map<std::string, other_type, my_comparator> my_map;
    

    Nach Stroustrup muss der Comparator jedoch für kleiner als und gleich transitiv sein.



  • Hallo,

    für diesen Fall solltest du eigentlich lower_bound/upper_bound verwenden können.
    Mit lower_bound bekommst du das erste Element, dass nicht kleiner als der Suchstring ist. Mit upper_bound das erste Element, dass größer ist als der Suchstring.

    typedef std::map<string, int> Map;
    Map m;
    m.insert(Map::value_type("ab", 1));
    m.insert(Map::value_type("abcdef", 2));
    m.insert(Map::value_type("xyz", 3));
    Map::iterator lIt = m.lower_bound("abc");
    

    Hier zeigt lIt nun auf den Eintrag ("abcdef", 2).

    typedef std::map<string, int> Map;
    Map m;
    m.insert(Map::value_type("ab", 1));
    m.insert(Map::value_type("xyz", 3));
    Map::iterator lIt = m.lower_bound("abc");
    

    Hier hingegen auf ("xyz", 3). Ist halt die Frage, was für dich in diesem Fall der "beste match" ist. Gegebenenfalls musst du halt den Suchstring, den du an lower_/upper_bound übergibst anpassen.
    Wenn du z.B. alle Einträge haben willst, die ein gemeinsames Präfix p haben:

    Map::iterator lIt = m.lower_bound("ab");
    Map::iterator uIt = m.upper_bound(std::string("ab")+(char)CHAR_MAX);
    cout << "Entries with prefix 'ab': " << endl;
    for (; lIt != uIt; ++lIt) {
      cout << lIt->first << endl;
    }
    


  • --.. ..- + ... .--. .- . -


Anmelden zum Antworten