Wir müssen uns keine Sorgen machen str kürzer sein als pre denn laut C-Standard (7.21.4.4/2):
Das strncmp Funktion vergleicht nicht mehr als n Zeichen (Zeichen, die einem Nullzeichen folgen, werden nicht verglichen) aus dem Array, auf das gezeigt wird s1 zu dem Array, auf das von gezeigt wird s2.”
Warum ist die Antwort nein? Ganz klar, die Antwort ist ja, es heißt strncmp.
– Jaspis
13. Februar 2017 um 0:39 Uhr
^ Es sollte offensichtlich sein, warum die Antwort nein ist. Ein Algorithmus, der verwendet strncmp und strlen heißt nicht “strncmp”.
– Jim Balter
1. August 2019 um 18:50 Uhr
Anscheinend gibt es dafür keine Standard-C-Funktion. So:
Beachten Sie, dass das Obige schön und klar ist, aber wenn Sie es in einer engen Schleife tun oder mit arbeiten sehr großen Saiten bietet es nicht die beste Leistung, da es die volle Länge beider Saiten vorne abtastet (strlen). Lösungen wie die von wj32 oder Christoph bieten möglicherweise eine bessere Leistung (obwohl dieser Kommentar zur Vektorisierung außerhalb meines Verständnisses von C liegt). Beachten Sie auch die Lösung von Fred Foo, die vermeidet strlen an str (Er hat Recht, es ist unnötig, wenn Sie verwenden strncmp Anstatt von memcmp). Ist nur wichtig für (sehr) große Saiten oder wiederholte Verwendung in engen Schleifen, aber wenn es darauf ankommt, ist es wichtig.
Ich sollte erwähnen, dass die üblich Die Sache wäre, dass die Zeichenfolge der erste Parameter ist und das Präfix für den zweiten. Aber ich habe sie wie oben beibehalten, weil Ihre Frage anscheinend so formuliert war … Die Reihenfolge liegt ganz bei Ihnen, aber ich hätte es wirklich andersherum machen sollen – die meisten Zeichenfolgenfunktionen nehmen die vollständige Zeichenfolge als erstes Argument, der Teilstring als zweites.
– TJ Crowder
22. Januar 2011 um 22:31 Uhr
Dies ist eine elegante Lösung, die jedoch einige Leistungsprobleme aufweist. Eine optimierte Implementierung würde niemals mehr als min(strlen(pre), strlen(str)) Zeichen aus jeder Zeichenfolge betrachten, noch würde sie jemals über die erste Nichtübereinstimmung hinausgehen. Wenn die Saiten lang wären, aber frühe Fehlanpassungen üblich wären, wäre es sehr leicht. Da diese Implementierung jedoch die volle Länge beider Zeichenfolgen im Voraus verwendet, erzwingt sie eine Worst-Case-Leistung, selbst wenn sich die Zeichenfolgen im allerersten Zeichen unterscheiden. Ob dies wirklich wichtig ist, hängt von den Umständen ab, aber es ist ein potenzielles Problem.
– Tom Karzes
6. Januar 2018 um 11:33 Uhr
@TomKarzes Sie können ersetzen memcmp zum strncmp hier und es ist schneller. Es gibt kein UB, weil beide Saiten bekanntermaßen mindestens haben lenpre Byte. strncmp prüft jedes Byte beider Strings auf NUL, aber die strlen Anrufe schon garantiert, dass es keine gibt. (Aber es hat immer noch den von Ihnen erwähnten Leistungseinbruch, wenn pre oder str sind länger als die eigentliche gemeinsame Anfangssequenz.)
– Jim Balter
1. August 2019 um 18:43 Uhr
@JimBalter – Sehr guter Punkt! Seit der Verwendung memcmp oben würde sich hier nicht von einer anderen Antwort aneignen, ich habe es in der Antwort geändert.
– TJ Crowder
2. August 2019 um 6:46 Uhr
PS Dies ist (jetzt) möglicherweise die schnellste Antwort auf einigen Maschinen mit einigen Zeichenfolgen, weil strlen und memcmp kann mit sehr schnellen Hardwareanweisungen implementiert werden, und die strlens kann die Zeichenfolgen in den Cache stellen, wodurch ein doppelter Speichertreffer vermieden wird. Auf solchen Maschinen strncmp könnte als zwei implementiert werden strlens und a memcmp einfach so, aber es wäre für einen Bibliotheksautor riskant, dies zu tun, da dies bei langen Zeichenfolgen mit kurzen gemeinsamen Präfixen viel länger dauern könnte. Hier ist dieser Treffer explizit und der strlens werden jeweils nur einmal durchgeführt (Fred Foo’s strlen + strncmp würde machen 3).
– Jim Balter
2. August 2019 um 17:06 Uhr
Christoph
Ich würde wahrscheinlich mitgehen strncmp()aber nur zum Spaß eine rohe Implementierung:
Das gefällt mir am besten – es gibt keinen Grund, eine der Saiten nach einer Länge zu scannen.
– Michael Burr
23. Januar 2011 um 6:22 Uhr
Ich würde wahrscheinlich auch mit strlen+strncmp gehen, aber obwohl es tatsächlich funktioniert, schreckt mich die ganze Kontroverse über seine vage Definition ab. Also werde ich das verwenden, danke.
– Sam Watkins
6. Januar 2015 um 3:26 Uhr
Dies ist wahrscheinlich langsamer als strncmpes sei denn, Ihr Compiler ist wirklich gut in der Vektorisierung, weil Glibc-Autoren das sicher sind 🙂
– Ciro Santilli OurBigBook.com
27. Juni 2015 um 12:39 Uhr
Diese Version sollte schneller sein als die strlen+strncmp-Version, wenn das Präfix nicht übereinstimmt, insbesondere wenn es bereits Unterschiede in den ersten Zeichen gibt.
– dpi
14. Juli 2018 um 0:22 Uhr
^ Diese Optimierung würde nur gelten, wenn die Funktion eingebettet ist.
Ich denke, Ihr 3. Beispiel sollte ein wahres Ergebnis haben.
– Michael Burr
23. Januar 2011 um 6:19 Uhr
mögliches Duplikat von stackoverflow.com/questions/15515088/…
– Urlaub
15. Oktober 2019 um 6:52 Uhr