Ich habe die Schnur
a.b.c.d
Ich möchte die Vorkommen von '.' auf eine idiomatische Weise, vorzugsweise ein Einzeiler.
(Zuvor hatte ich diese Einschränkung als "ohne Schleife" ausgedrückt, falls Sie sich fragen, warum alle versuchen, ohne Schleife zu antworten.)
Antworten:
Mein 'idiomatischer Einzeiler' dafür ist:
Warum selbst schreiben, wenn es bereits in Commons Lang ist ?
Der Oneliner von Spring Framework hierfür ist:
quelle
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Wie beantwortet dogbane in einer doppelten Frage.Wie wäre es damit. Es verwendet keinen regulären Ausdruck darunter, sollte also schneller sein als einige der anderen Lösungen und keine Schleife verwenden.
quelle
Fassen Sie andere Antworten zusammen und wissen Sie, wie ich dies mit einem Einzeiler tun kann:
1) Verwenden von Apache Commons
2) Verwenden von Spring Frameworks
3) Mit ersetzen
4) Verwenden von replaceAll (Fall 1)
5) Verwenden von replaceAll (Fall 2)
6) Split verwenden
7) Verwenden von Java8 (Fall 1)
8) Die Verwendung von Java8 (Fall 2) ist für Unicode möglicherweise besser als für Fall 1
9) Verwenden von StringTokenizer
Aus dem Kommentar : Seien Sie vorsichtig mit dem StringTokenizer, für abcd funktioniert es, aber für a ... bc ... d oder ... abcd oder a .... b ...... c ..... d ... oder etc. es wird nicht funktionieren. Es wird nur zählen. zwischen Zeichen nur einmal
Mehr Infos in Github
Leistungstest (mit JMH , mode = AverageTime,
0.010
besser abschneiden als0.351
):quelle
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Früher oder später muss sich etwas wiederholen. Es ist für Sie viel einfacher, die (sehr einfache) Schleife zu schreiben, als etwas zu verwenden,
split
das viel leistungsfähiger ist als Sie benötigen.Kapselung der Schleife auf jeden Fall in einer separaten Methode, z
Dann brauchen Sie die Schleife nicht in Ihrem Hauptcode - aber die Schleife muss irgendwo da sein.
quelle
length()
Anruf außerhalb der Schleife könnte Leistung machen schlimmer , wie oben von @ShuggyCoUk ein paar Bemerkungen erwähnt.Ich hatte eine ähnliche Idee wie Mladen, aber das Gegenteil ...
quelle
replaceAll()
und ausgeführt werdenlength()
. Nun, wenn es nicht sichtbar ist, existiert es nicht; o)ReplaceAll (".") Würde alle Zeichen ersetzen.
Die Lösung von PhiLho verwendet ReplaceAll ("[^.]", ""), Das nicht maskiert werden muss, da [.] Das Zeichen 'Punkt' und nicht 'irgendein Zeichen' darstellt.
quelle
Meine "idiomatische Einzeiler" -Lösung:
Haben Sie keine Ahnung, warum eine Lösung, die StringUtils verwendet, akzeptiert wird.
quelle
quelle
Ein kürzeres Beispiel ist
quelle
Hier ist eine Lösung ohne Schleife:
Nun, es gibt eine Schleife, aber sie ist unsichtbar :-)
- Yonatan
quelle
Ich mag die Idee nicht, einen neuen String für diesen Zweck zuzuweisen. Und da der String bereits ein char-Array auf der Rückseite hat, in dem er seinen Wert speichert, ist String.charAt () praktisch kostenlos.
erledigt den Trick ohne zusätzliche Zuordnungen, die in einer Zeile oder weniger erfasst werden müssen, mit nur J2SE.
quelle
charAt
iteriert durch 16-Bit-Codepunkte, nicht durch Zeichen! Achar
in Java ist kein Zeichen. Diese Antwort impliziert also, dass es kein Unicode-Symbol geben darf, wobei ein hoher Ersatz gleich dem Codepunkt von istdelim
. Ich bin nicht sicher, ob es für den Punkt korrekt ist, aber im Allgemeinen ist es möglicherweise nicht korrekt.Okay, inspiriert von Yonatans Lösung, hier ist eine, die rein rekursiv ist - die einzigen verwendeten Bibliotheksmethoden sind
length()
undcharAt()
, von denen keine eine Schleife ausführt:Ob Rekursion als Schleife zählt, hängt davon ab, welche genaue Definition Sie verwenden, aber sie ist wahrscheinlich so nah wie möglich.
Ich weiß nicht, ob die meisten JVMs heutzutage eine Schwanzrekursion durchführen ... wenn nicht, erhalten Sie natürlich den gleichnamigen Stapelüberlauf für entsprechend lange Zeichenfolgen.
quelle
Inspiriert von Jon Skeet, einer Non-Loop-Version, die Ihren Stack nicht sprengt. Auch ein nützlicher Ausgangspunkt, wenn Sie das Fork-Join-Framework verwenden möchten.
(Haftungsausschluss: Nicht getestet, nicht kompiliert, nicht sinnvoll.)
Vielleicht die beste Möglichkeit (Single-Threaded, keine Ersatzpaar-Unterstützung), es zu schreiben:
quelle
Ich bin mir nicht sicher, wie effizient dies ist, aber es ist der kürzeste Code, den ich schreiben kann, ohne Bibliotheken von Drittanbietern einzubringen:
quelle
return (content.split(target, -1).length - 1);
. Standardmäßig werden Vorkommen am Ende der Zeichenfolge im Array weggelassen, die sich aus split () ergeben. Siehe die DokuMit Java-8Sie können auch Streams verwenden, um dies zu erreichen. Natürlich gibt es eine Iteration hinter den Kulissen, aber Sie müssen sie nicht explizit schreiben!
quelle
.codePoints()
anstelle von.chars()
würde dann jeden Unicode-Wert unterstützen (einschließlich derer, die Ersatzpaare erfordern)Es ist auch möglich, redu in Java 8 zu verwenden, um dieses Problem zu lösen:
Ausgabe:
quelle
Komplette Probe:
Anruf:
quelle
Der einfachste Weg, um die Antwort zu erhalten, ist wie folgt:
quelle
Wenn Sie das Spring-Framework verwenden, können Sie auch die Klasse "StringUtils" verwenden. Die Methode wäre "countOccurrencesOf".
quelle
Sie können die
split()
Funktion in nur einem Zeilencode verwendenquelle
limit
in diesem überladenen Split-Methodenaufruf auf Null gesetzt wird. Ein Beispiel: Es"1##2#3#####".split("#")
wird nur ein Array der Größe 4 ([0:"1";1:""; 2:"2"; 3:"3"]
) anstelle der Größe 9 ([0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
) ausgegeben.quelle
quelle
Während Methoden es ausblenden können, gibt es keine Möglichkeit, ohne eine Schleife (oder Rekursion) zu zählen. Sie möchten jedoch aus Leistungsgründen ein char [] verwenden.
Die Verwendung von replaceAll (das ist RE) klingt nicht nach dem besten Weg.
quelle
Nun, mit einer ganz ähnlichen Aufgabe bin ich auf diesen Thread gestoßen. Ich habe keine Einschränkung der Programmiersprache festgestellt und da groovy auf einem Java-VM ausgeführt wird: So konnte ich mein Problem mit Groovy lösen.
erledigt.
quelle
Eine viel einfachere Lösung wäre, die Zeichenfolge nur anhand des Zeichens zu teilen, mit dem Sie sie abgleichen.
Zum Beispiel,
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
Dies ergibt 4 im Fall von:
getOccurences("o", "something about a quick brown fox");
quelle
Irgendwo im Code muss sich etwas wiederholen. Der einzige Weg, dies zu umgehen, ist ein vollständiges Abrollen der Schleife:
... usw., aber dann sind Sie derjenige, der die Schleife manuell im Quellcode-Editor ausführt - anstelle des Computers, auf dem sie ausgeführt wird. Siehe den Pseudocode:
quelle
Hier ist eine etwas andere Rekursionslösung:
quelle
Warum nicht einfach das Zeichen teilen und dann die Länge des resultierenden Arrays ermitteln? Die Array-Länge ist immer die Anzahl der Instanzen + 1. Richtig?
quelle
Der folgende Quellcode gibt Ihnen die Anzahl der Vorkommen einer bestimmten Zeichenfolge in einem vom Benutzer eingegebenen Wort an: -
quelle
quelle