Gibt es eine bessere Möglichkeit, mehrere Zeichenbereiche zu bestimmen?

8

Ich schreibe gerade Code in C, der Symbole und Zahlen aus ganzen ASCII-Zeichen auswählt. Als Anfänger des Programmierers habe ich normalerweise

gemacht %Vor%

für die Variable i zwischen 25 ~ 50, 100 ~ 200 (exklusiv), um die Bedingung zu erfüllen.

Wenn ich mehrere Bereiche wie 32 ~ 64 ( ! to @ ) und 91 ~ 96 ( [ to ' ) und 123 ~ 126 ( { to ~ ) festlegen möchte, wäre es besser (kürzerer oder einfacherer Code) Oder sollte ich bei dieser Methode bleiben, fügen Sie jeden Bereich wie im obigen Code hinzu?

    
Kagamin 13.07.2016, 04:55
quelle

7 Antworten

14

Für Ihren speziellen Fall würde die <ctype.h> Sammlung von Funktionen ausreichen

%Vor%

Zusätzlicher Bonus: Es funktioniert sogar auf Nicht-ASCII-Systemen.

    
a3f 13.07.2016, 05:15
quelle
2

Sie können eine Funktion schreiben, die überprüft, ob der Wert zu einem der angegebenen Bereiche gehört:

%Vor%

Es macht Bearbeitungsbereiche viel einfacher und verbessert die Lesbarkeit. Wenn Sie weiterhin alle Bereiche in der Bedingungsklausel wie in Ihrem Beispiel schreiben, sollten Sie Bereiche wie

überprüfen %Vor%

Es sieht aus wie mathematische Notation ( x < a < y ) und scheint auch einfacher zu lesen.

    
Sergey 13.07.2016 05:15
quelle
1

Wenn Sie Einzelbytezeichen verwenden, können Sie möglicherweise eine bessere Leistung erzielen, indem Sie ein Array von Flags verwenden und entweder einzelne Bits oder ganze Bytes festlegen, um Zeichenwerte in einem der Bereiche anzugeben.

Wenn Sie Code für einen Intel-Prozessor schreiben, der die SSE 4.2-Anweisungen unterstützt, sollten Sie in Betracht ziehen, PCMPISTRI o.ä. zu verwenden, die bis zu 16 einzelne Byte-Zeichen mit bis zu 8 verschiedenen Bereichen in einer Anweisung vergleichen können.

    
Simon Spero 13.07.2016 13:47
quelle
1

Meine Antwort wäre "es kommt darauf an". :)

Wenn isalpha() und Freunde von ctype.h tun, was Sie wollen, dann verwenden Sie sie unbedingt.

Aber wenn nicht ...

Wenn Sie nur zwei Bereiche hatten, wie in Ihrem Beispielausschnitt, denke ich nicht, dass es zu unordentlich aussieht. Wenn es mehr gibt, setzen Sie den Bereichstest möglicherweise in eine (Inline-) Funktion, um die Anzahl der gleichzeitig sichtbaren Booleschen Werte zu reduzieren:

%Vor%

(Oder geben Sie B(n,a,b) ein, wenn Sie die Bildschirmgröße speichern möchten.)

Wenn sich die Bereiche in der Laufzeit ändern oder viele davon vorhanden sind, setzen Sie die Grenzwerte in struct und durchlaufen Sie ein Array davon. Wenn es wirklich viele gibt, sortiere die Liste und mache etwas Kluges damit, wie eine binäre Suche über die unteren Grenzen (oder was auch immer). Aber für eine kleine Anzahl würde ich nicht stören.

Wenn der Gesamtbereich zulässiger Werte klein ist (wie vorzeichenlose Zeichen mit Werten 0..255), aber die Anzahl separater "Bereiche" groß ist ("alle mit Primärwerten"), dann erstellen Sie eine Tabelle (Bitmap ) der Werte, und teste das. Erstellen Sie den Tisch nach Belieben. ( isalpha() wird wahrscheinlich so implementiert)

%Vor%     
ilkkachu 13.07.2016 16:35
quelle
0

Sie können eine Funktion schreiben wie:

%Vor%

Dann können Sie diese Funktion verwenden und den Code sauber und einfach halten.

    
hexiecs 13.07.2016 05:11
quelle
0

Sie können die Duplizierung von l<x && x<h in einem Makro oder einer Inline-Funktion ausblenden, aber ich habe festgestellt, dass es sich selten lohnt - es ist nicht so lesenswert wie Python l<x<h -Syntax und gerät schnell außer Kontrolle, wenn Sie anfangen haben Makros für alle inklusive Grenzen Möglichkeiten. Entweder enden Sie mit einer lächerlich langen Namenskonvention ( between_inc_inc , between_inc_exc , ... die einen Fehler bei der Auszahlung des Schecks an erster Stelle bedeutet) oder Sie lassen den Leser sich Gedanken über Ihre Reichweiten-Checks machen (" between(i, 50, 100) .. Ist es ein [,) Bereich? a [,] eins? (überprüft den Code) Nein, es ist ein (,) "), was furchtbar ist, wenn Sie Fehler von einer Seite jagen.

OTOH, ich bin dafür bekannt, "single letter macros" zu missbrauchen, die ich genau definiere, wo und wie sie gebraucht werden, und sie sind sofort undefiniert. Obwohl sie hässlich aussehen können, ist der Punkt, dass sie extrem lokal sind und genau das tun, was getan werden muss, so dass keine Zeit verschwendet wird, um sie aufzusuchen, es gibt keine kryptischen Parameter und sie können die Masse ausgleichen der wiederholten Berechnung.

In Ihrem Fall, wenn die Liste sehr lang ist, kann ich das tun

%Vor%

(niemals in einer Kopfzeile!)

Was die Lesbarkeit verbessert, ist die Verwendung von Zeichenliteralen anstelle von ASCII-Zahlen: Wenn Sie beispielsweise den a-z-Bereich verwenden möchten, verwenden Sie 'a'<=i && i<='z' .

Sie scheinen alphabetische und nicht druckbare Zeichen ausschließen zu wollen: Sie können das mit

machen %Vor%     
Matteo Italia 13.07.2016 05:11
quelle
0
%Vor%

Sie können AddRange aufrufen, um so viele Bereiche hinzuzufügen, wie Sie möchten, und dann können Sie überprüfen, ob eine Zahl in Reichweite ist.

%Vor%     
meJustAndrew 13.07.2016 06:27
quelle

Tags und Links