Tengo la cuerda
a.b.c.d
Quiero contar las ocurrencias de '.' de manera idiomática, preferiblemente de una sola línea.
(Anteriormente había expresado esta restricción como "sin bucle", en caso de que se pregunte por qué todos intentan responder sin usar un bucle).
Respuestas:
Mi 'frase idiomática' para esto es:
¿Por qué escribirlo usted mismo cuando ya está en commons lang ?
El marco de Spring Framework para esto es:
fuente
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Como respondió dogbane en una pregunta duplicada.Qué tal esto. No usa regexp debajo, por lo que debería ser más rápido que algunas de las otras soluciones y no usará un bucle.
fuente
Resuma otra respuesta y lo que sé todas las formas de hacer esto usando una línea:
1) Uso de Apache Commons
2) Usando Spring Framework's
3) Usando reemplazar
4) Uso de replaceAll (caso 1)
5) Uso de replaceAll (caso 2)
6) Usando split
7) Uso de Java8 (caso 1)
8) Usar Java8 (caso 2), puede ser mejor para Unicode que el caso 1
9) Usando StringTokenizer
Del comentario : Tenga cuidado con el StringTokenizer, para abcd funcionará pero para un ... bc ... d o ... abcd o a .... b ...... c ..... d ... o etc. no funcionará. Simplemente contará para. entre personajes solo una vez
Más información en github
Prueba de rendimiento (usando JMH , mode = AverageTime, puntaje
0.010
mejor entonces0.351
):fuente
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Tarde o temprano, algo tiene que repetirse. Es mucho más simple para usted escribir el ciclo (muy simple) que usar algo como lo
split
que es mucho más poderoso de lo que necesita.Por supuesto, encapsule el bucle en un método separado, p. Ej.
Entonces no necesita tener el bucle en su código principal, pero el bucle debe estar allí en alguna parte.
fuente
length()
llamada exterior del bucle podría hacer que el rendimiento es peor , como se ha mencionado por @ShuggyCoUk algunos comentarios hacia arriba.Tuve una idea similar a Mladen, pero todo lo contrario ...
fuente
replaceAll()
ylength()
. Bueno, si no es visible, no existe; o)Reemplazar todo (".") Reemplazaría todos los caracteres.
La solución de PhiLho utiliza Reemplazar todo ("[^.]", ""), Que no necesita ser escapado, ya que [.] Representa el carácter 'punto', no 'ningún carácter'.
fuente
Mi solución 'idiomática de una línea':
No tengo idea de por qué se acepta una solución que utiliza StringUtils.
fuente
fuente
Un ejemplo más corto es
fuente
Aquí hay una solución sin bucle:
bueno, hay un bucle, pero es invisible :-)
- Yonatan
fuente
No me gusta la idea de asignar una nueva cadena para este propósito. Y como la cadena ya tiene una matriz de caracteres en la parte posterior donde almacena su valor, String.charAt () es prácticamente gratis.
hace el truco, sin asignaciones adicionales que necesitan colección, en 1 línea o menos, con solo J2SE.
fuente
charAt
itera a través de puntos de código de 16 bits, no caracteres! Achar
en Java no es un personaje. Entonces, esta respuesta implica que no debe haber un símbolo Unicode con un sustituto alto que sea igual al punto de código dedelim
. No estoy seguro de si es correcto para el punto, pero en general podría no ser correcto.Bien, inspirado en la solución de Yonatan, aquí hay uno que es puramente recursivo: los únicos métodos de biblioteca utilizados son
length()
ycharAt()
ninguno de los cuales realiza ningún bucle:Si la recursividad cuenta como bucle depende de la definición exacta que use, pero probablemente sea lo más cerca que pueda estar.
No sé si la mayoría de las JVM hacen recursión de cola en estos días ... si no, obtendrá el desbordamiento epónimo de pila para cadenas adecuadamente largas, por supuesto.
fuente
Inspirado por Jon Skeet, una versión sin bucle que no volará tu stack. También es un punto de partida útil si desea utilizar el framework fork-join.
(Descargo de responsabilidad: no probado, no compilado, no sensible).
Quizás la mejor manera (de un solo subproceso, sin soporte de par sustituto) para escribirlo:
fuente
No estoy seguro de la eficacia de esto, pero es el código más corto que podría escribir sin traer libs de terceros:
fuente
return (content.split(target, -1).length - 1);
. Por omisión, las ocurrencias al final de la cadena se omiten en la matriz resultante de split (). Ver el DokuCon java-8También podría usar transmisiones para lograr esto. Obviamente hay una iteración detrás de escena, ¡pero no tienes que escribirla explícitamente!
fuente
.codePoints()
lugar de.chars()
sería compatible con cualquier valor Unicode (incluidos los que requieren pares sustitutos)También es posible usar reduce en Java 8 para resolver este problema:
Salida:
fuente
Muestra completa:
Llamada:
fuente
La forma más sencilla de obtener la respuesta es la siguiente:
fuente
En caso de que esté usando Spring Framework, también puede usar la clase "StringUtils". El método sería "countOccurrencesOf".
fuente
Puede usar la
split()
función en un solo código de líneafuente
limit
se establece en cero en esta llamada al método dividido sobrecargado. Un ejemplo:"1##2#3#####".split("#")
solo producirá una matriz de tamaño 4 ([0:"1";1:""; 2:"2"; 3:"3"]
) en lugar de tamaño 9 ([0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
).fuente
fuente
Si bien los métodos pueden ocultarlo, no hay forma de contar sin un bucle (o recursividad). Sin embargo, desea utilizar un char [] por razones de rendimiento.
El uso de replaceAll (es decir, RE) no parece ser la mejor manera de hacerlo.
fuente
Bueno, con una tarea bastante similar me topé con este hilo. No vi ninguna restricción de lenguaje de programación y desde que groovy se ejecuta en un java vm: Así es como pude resolver mi problema usando Groovy.
hecho.
fuente
Una solución mucho más fácil sería dividir la cadena en función del carácter con el que coincida.
Por ejemplo,
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
Esto devolverá 4 en el caso de:
getOccurences("o", "something about a quick brown fox");
fuente
En algún lugar del código, algo tiene que repetirse. La única forma de evitar esto es desenrollar completamente el bucle:
... etc, pero entonces usted es el que realiza el bucle, manualmente, en el editor de origen, en lugar de la computadora que lo ejecutará. Ver el pseudocódigo:
fuente
Aquí hay una solución de recursión de estilo ligeramente diferente:
fuente
¿Por qué no simplemente dividir en el personaje y luego obtener la longitud de la matriz resultante? la longitud de la matriz siempre será número de instancias + 1. ¿Correcto?
fuente
El siguiente código fuente le dará no. De ocurrencias de una cadena dada en una palabra ingresada por el usuario: -
fuente
fuente