J'ai la ficelle
a.b.c.d
Je veux compter les occurrences de '.' de manière idiomatique, de préférence une doublure.
(Auparavant, j'avais exprimé cette contrainte comme "sans boucle", au cas où vous vous demanderiez pourquoi tout le monde essaie de répondre sans utiliser de boucle).
Réponses:
Mon «one-liner idiomatique» pour cela est:
Pourquoi l'écrire vous-même quand il est déjà en langage commun ?
Oneliner de Spring Framework pour cela est:
la source
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Comme l'a répondu Dogbane dans une question en double.Que dis-tu de ça. Il n'utilise pas regexp en dessous, donc devrait être plus rapide que certaines des autres solutions et n'utilisera pas de boucle.
la source
Résumez les autres réponses et ce que je sais de toutes les façons de le faire en utilisant une ligne:
1) Utiliser Apache Commons
2) Utilisation de Spring Framework
3) Utilisation de replace
4) Utilisation de replaceAll (cas 1)
5) Utilisation de replaceAll (cas 2)
6) Utilisation du split
7) Utilisation de Java8 (cas 1)
8) Utiliser Java8 (cas 2), peut être meilleur pour unicode que le cas 1
9) Utilisation de StringTokenizer
Du commentaire : Attention au StringTokenizer, pour abcd ça marchera mais pour a ... bc ... d ou ... abcd ou a .... b ...... c ..... d ... ou etc. cela ne fonctionnera pas. Ça va juste compter. entre les personnages juste une fois
Plus d'infos sur github
Test de performance (en utilisant JMH , mode = AverageTime,
0.010
mieux score alors0.351
):la source
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Tôt ou tard, quelque chose doit boucler. Il est beaucoup plus simple d'écrire la boucle (très simple) que d'utiliser quelque chose comme
split
qui est beaucoup plus puissant que nécessaire.Par tous les moyens encapsuler la boucle dans une méthode distincte, par exemple
Ensuite, vous n'avez pas besoin d'avoir la boucle dans votre code principal - mais la boucle doit être là quelque part.
la source
length()
appel en dehors de la boucle pourrait détériorer les performances , comme mentionné par @ShuggyCoUk quelques commentaires plus haut.J'avais une idée similaire à Mladen, mais le contraire ...
la source
replaceAll()
etlength()
. Eh bien, s'il n'est pas visible, il n'existe pas; o)ReplaceAll (".") Remplacerait tous les caractères.
La solution de PhiLho utilise ReplaceAll ("[^.]", ""), Qui n'a pas besoin d'être échappé, car [.] Représente le caractère 'point', pas 'n'importe quel caractère'.
la source
Ma solution `` one-liner idiomatique '':
Je ne sais pas pourquoi une solution qui utilise StringUtils est acceptée.
la source
la source
Un exemple plus court est
la source
voici une solution sans boucle:
eh bien, il y a une boucle, mais elle est invisible :-)
- Yonatan
la source
Je n'aime pas l'idée d'allouer une nouvelle chaîne à cet effet. Et comme la chaîne a déjà un tableau de caractères à l'arrière où elle stocke sa valeur, String.charAt () est pratiquement libre.
fait l'affaire, sans allocations supplémentaires qui doivent être collectées, en 1 ligne ou moins, avec seulement J2SE.
la source
charAt
itère à travers des points de code 16 bits et non des caractères! Achar
en Java n'est pas un personnage. Cette réponse implique donc qu'il ne doit pas y avoir de symbole Unicode avec un substitut élevé égal au point de code dedelim
. Je ne sais pas si c'est correct pour le point, mais en général ce n'est peut-être pas correct.D'accord, inspiré par la solution de Yonatan, en voici une qui est purement récursive - les seules méthodes de bibliothèque utilisées sont
length()
etcharAt()
, aucune ne fait de boucle:Le fait que la récursivité compte comme une boucle dépend de la définition exacte que vous utilisez, mais elle est probablement aussi proche que possible.
Je ne sais pas si la plupart des JVM font une récursion de queue ces jours-ci ... sinon vous obtiendrez le débordement de pile éponyme pour des chaînes convenablement longues, bien sûr.
la source
Inspiré par Jon Skeet, une version sans boucle qui ne soufflera pas votre pile. Point de départ également utile si vous souhaitez utiliser le framework fork-join.
(Avertissement: non testé, non compilé, non raisonnable.)
Peut-être la meilleure façon (monothread, pas de support de paire de substitution) de l'écrire:
la source
Je ne suis pas sûr de l'efficacité de cela, mais c'est le code le plus court que j'ai pu écrire sans apporter de bibliothèques tierces:
la source
return (content.split(target, -1).length - 1);
. Par défaut, les occurrences à la fin de la chaîne sont omises dans le tableau résultant de split (). Voir le DokuAvec java-8vous pouvez également utiliser des flux pour y parvenir. Évidemment, il y a une itération dans les coulisses, mais vous n'avez pas à l'écrire explicitement!
la source
.codePoints()
au lieu de.chars()
prendrait alors en charge toute valeur Unicode (y compris celles nécessitant des paires de substitution)Il est également possible d'utiliser réduire dans Java 8 pour résoudre ce problème:
Production:
la source
Échantillon complet:
Appel:
la source
La façon la plus simple d'obtenir la réponse est la suivante:
la source
Si vous utilisez Spring Framework, vous pouvez également utiliser la classe "StringUtils". La méthode serait "countOccurrencesOf".
la source
Vous pouvez utiliser la
split()
fonction dans un seul code de lignela source
limit
est défini sur zéro dans cet appel de méthode de fractionnement surchargé. Un exemple:"1##2#3#####".split("#")
ne donnera qu'un tableau de taille 4 ([0:"1";1:""; 2:"2"; 3:"3"]
) au lieu de la taille 9 ([0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
).la source
la source
Bien que les méthodes puissent le masquer, il n'y a aucun moyen de compter sans boucle (ou récursivité). Vous souhaitez cependant utiliser un caractère [] pour des raisons de performances.
L'utilisation de replaceAll (c'est-à-dire RE) ne semble pas être la meilleure solution.
la source
Eh bien, avec une tâche assez similaire, je suis tombé sur ce fil. Je n'ai vu aucune restriction de langage de programmation et puisque groovy s'exécute sur une machine virtuelle java: voici comment j'ai pu résoudre mon problème en utilisant Groovy.
terminé.
la source
Une solution beaucoup plus facile serait de simplement diviser la chaîne en fonction du caractère avec lequel vous le faites correspondre.
Par exemple,
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
Cela retournera 4 dans le cas de:
getOccurences("o", "something about a quick brown fox");
la source
Quelque part dans le code, quelque chose doit boucler. Le seul moyen de contourner cela est un déroulement complet de la boucle:
... etc, mais c'est vous qui faites la boucle, manuellement, dans l'éditeur de source - au lieu de l'ordinateur qui l'exécutera. Voir le pseudocode:
la source
Voici une solution de récursion de style légèrement différente:
la source
Pourquoi ne pas simplement diviser le caractère, puis obtenir la longueur du tableau résultant. la longueur du tableau sera toujours le nombre d'instances + 1. N'est-ce pas?
la source
Le code source suivant vous donnera pas d'occurrences d'une chaîne donnée dans un mot entré par l'utilisateur: -
la source
la source