C ++: Wie überprüfe ich, ob ein Zeichen zwischen einem bestimmten Zeichenbereich liegt?
Sprich, wenn ich einen String-Namen habe. Ich möchte überprüfen, ob das erste Zeichen dieser Zeichenfolge zwischen 'a' und 'n' liegt.
Wie mache ich das?
To tun (name [0] == 'a') (name [0] == 'b') ... wäre zu lang ...
Wenn möglich, möchte ich eine Lösung, die elegant mit ASCII-Werten umgeht.
Wenn Sie überprüfen möchten, ob das erste Zeichen Ihrer Zeichenfolge zwischen 'a' und 'n' liegt, sollten Sie zum Beispiel name[0] >= 'a' && name[0] <= 'n'
korrekt ausführen.
Beachten Sie jedoch, dass Sie, wenn Sie in Ihrem Brief auch Großbuchstaben als erstes Zeichen haben können, stattdessen (name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N')
überprüfen müssen.
Sie können std::all_of
in Kombination mit einem Lambda-Ausdruck :
Dies ist für die meisten Anwendungen portabel genug, da der Zeichensatz normalerweise gemäß den ASCII-Konventionen implementiert wird, wie in § 2.3 / 14 erklärt:
Die Glyphen für die Elemente des grundlegenden Quellzeichensatzes sollen Zeichen aus der Teilmenge von ISO / IEC 10646 identifizieren, die dem ASCII-Zeichensatz entspricht. Da das Mapping von Quelldateizeichen auf den Quellzeichensatz (in Übersetzungsphase 1 beschrieben) als implementierungsdefiniert angegeben wird, muss jedoch eine Implementierung dokumentiert werden, in der die grundlegenden Quellzeichen in Quelldateien dargestellt werden.
Die Komplexität des obigen Algorithmus ist O(n)
. Die Alternative (überprüfen Sie jedes Zeichen im Zeichenbereich mit k
-Zeichen) ist O(n*k)
, aber Sie können zumindest sicher sein, dass es keine Implementierung definiert ist.
Wenn Sie sicher sind, dass der verwendete Zeichensatz auf Ihrer Plattform ASCII ist, können Sie etwas wie:
verwenden %Vor%Ansonsten sollte so etwas funktionieren:
%Vor%Schleife durch die Zeichenfolge, überprüfe jedes Zeichen und schaue, ob es zwischen a und n bleibt, wobei str [i] & gt; 'a' und str [i] & lt; 'n'
verwendet werdenFür einen zusammenhängenden Bereich von Zeichen können Sie:
%Vor% Um Groß- / Kleinschreibung zu berücksichtigen, verwenden Sie tolower()
und den Kleinbuchstabenbereich:
Für einen nicht zusammenhängenden Bereich müssen Sie möglicherweise eine Maske erstellen. In diesem Beispiel werde ich nach Vokalen suchen (aus Gründen der Kürze, da es nur 5 gibt, aber jede Kombination in einem Bereich von 32 könnte verwendet werden oder 64 mit einigen Modifikationen ... tatsächlich würde eine 64-Bit-Maske auf einer 64-Bit-Plattform die Notwendigkeit einer Fallbehandlung eliminieren.
%Vor% Beachten Sie, dass diese Implementierungen keine Verzweigungen enthalten. Die Verwendung eines unsignierten Vergleichs kann jedoch eine automatische Compiler-Vektorisierung verhindern (Intel-Intrinsics, haben keinen vorzeichenlosen Vergleich) ... wenn das Ihr Ziel ist, können Sie stattdessen 2 &
ed-Vergleiche verwenden. Diese Methode funktioniert möglicherweise nicht auf Nicht-ASCII-Systemen, abhängig vom Abstand der Zeichen.
GCC
%Vor%Clang
%Vor%ICC
%Vor%Zusätzlich zur standardmäßigen stackoverflow-Lizenz wird dieser Code für die Public Domain freigegeben