2016-04-19 4 views
0

Ich habe einen großen STL-Container von std::string (Hunderttausende von Einträgen). Ich benutze gerade eine vector, aber ich bin glücklich, mich zu ändern. Die Inhalte sind alphabetisch sortiert und bestehen aus alphabetischen Kleinbuchstaben a-z plusñ.Finden Sie alle Strings (nicht-niedriger ASCII) beginnend mit einem Präfix in einem geordneten STL-Container

Ich versuche, eine Funktion zu implementieren, die eine const std::string& prefix empfängt und ein Paar Iteratoren zurückgibt, wobei einer auf das erste Element zeigt, das mit einem solchen Präfix beginnt, und das andere auf den letzten verweist. Wenn keine Zeichenfolgen den Kriterien entsprechen, geben Sie zwei identische Iteratoren zurück. Ich brauche Effizienz beim Nachschlagen, weil der Vektor sehr groß ist, also möchte ich ihn für eine binäre Suche verwenden.

Ich denke, std::lower_bound ist, was ich suche, aber ich vermisse eine Funktion zu vergleichen std::string s, die mit der spanischen ñ umgehen kann.

+0

Verwenden Sie UTF-8? Solange Sie die gleiche Codierung in Ihrer Such-Präfix-Zeichenfolge verwenden, die Sie im Vektor verwenden, sollten Sie in Ordnung sein. Für die Geschwindigkeit können Sie die Präfixlänge in das Lambda eintragen und die entsprechende Überladung von 'std :: string :: compare' aufrufen. – paddy

+0

Sie können eine benutzerdefinierte Vergleichsfunktion schreiben, die an 'lower_bound()' übergeben wird, aber jeder von Ihnen durchgeführte Vergleich muss Zeichensatz/Gebietsschema berücksichtigen, da 'ñ' kein ASCII ist. 'std :: string' kennt nur' char' Werte und hat kein Konzept von Zeichensatz/Gebietsschema, also müssen Sie es manuell behandeln. 'ñ' kann ein anderer' char'-Wert in verschiedenen Zeichensätzen sein, und es existiert überhaupt nicht in einigen Zeichensätzen. –

Antwort

1

Sie können den gesamten Bereich der gleichen Werte mit std::equal_range erhalten. Sie erhalten ein Paar Iteratoren, einen am Anfang und einen nach dem Ende des Bereichs, wenn mindestens eine übereinstimmende Zeichenfolge in der Sammlung vorhanden ist. Wenn die Zeichenfolge nicht vorhanden ist, gibt es zwei gleiche Iteratoren an der ersten Stelle unmittelbar nach der Position, zu der die Zeichenfolge gehören würde, wenn sie vorhanden wäre.

Vorausgesetzt, dass Sie nur eine identische Teilzeichenfolge suchen, sollte ein normaler String-Vergleich (der ersten N Zeichen) gut funktionieren. Wenn Sie zum Beispiel Dinge wie ein Paar Eingabestrings unterstützen und alle Eingaben zwischen ihnen finden möchten, mussten Sie von (say) "m *" bis "o *" (mit Ihren "ñ *" - Strings) suchen so behandelt werden, als ob sie zwischen den beiden kämen), dann müssten Sie ein bisschen schicker werden (das Übliche besteht dann darin, eine Kollationstabelle mit dem Zeichencode als Index und der relativen Reihenfolge als Wert an jeder Position zu erstellen).

+0

Können Sie den Präfix mit dem Standard 'equal_range()' vergleichen, oder ist es nur ein Vergleich in voller Länge? Oder benötigen Sie einen benutzerdefinierten Compare-Funktor, um die Präfix-Übereinstimmung zu implementieren? –

+0

@RemyLebeau: Sie können ein Vergleichsobjekt übergeben, das den von Ihnen angegebenen Vergleich durchführt. In diesem Fall würden Sie eine übergeben, die (zum Beispiel) einen Vergleich wie folgt durchführt: return a_str (0, N)

+0

Ich würde wahrscheinlich stattdessen eine der 'std :: string :: compare() 'Überladungen verwenden, um unnötige Zuweisungen zu vermeiden, wie zum Beispiel' return (a.compare (0, b.size(), b) == 0); ' –

Verwandte Themen