¿Por qué el siguiente algoritmo no se detiene para mí?
En el código de abajo, str
es la cadena en la que estoy buscando, y findStr
es la cadena de ocurrencias de las que estoy tratando de encontrar.
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = str.indexOf(findStr,lastIndex);
if( lastIndex != -1)
count++;
lastIndex += findStr.length();
}
System.out.println(count);
SOY
¿Qué hay de usar StringUtils.countMatches de Apache Commons Lang?
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));
Eso da como resultado:
3
-
No importa cuán correcta sea esta sugerencia, no puede aceptarse como la solución ya que no responde la pregunta de OP
– kommradHomer
12 de julio de 2014 a las 11:36
-
¿Está obsoleto o algo así? Mi IDE no reconoce
– Vamsi Pavan Mahesh
18/07/2014 a las 16:30
-
@VamsiPavanMahesh StringUtils es una biblioteca de Apache Commons. Chequea aquí : commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
– Anup
15/09/2015 a las 11:33
-
Esta respuesta es una copia de la respuesta de Peter Lawrey un día antes (ver más abajo).
– Zona
14/03/2016 a las 14:36
-
StringUtils
no tienecountMatches
método.– camisa a cuadros
10 de mayo de 2018 a las 9:19
olivier
Tu lastIndex += findStr.length();
se colocó fuera de los corchetes, lo que provocó un bucle infinito (cuando no se encontró ninguna ocurrencia, lastIndex siempre findStr.length()
).
Aquí está la versión fija:
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = str.indexOf(findStr, lastIndex);
if (lastIndex != -1) {
count++;
lastIndex += findStr.length();
}
}
System.out.println(count);
-
Esto fallará para la cadena “aaa” y la subcadena “aa”. Devolverá 1 mientras la cuenta es dos. Los índices de las ocurrencias son [0,1]
– Niko
14/10/2021 a las 21:31
-
@Niko El resultado correcto depende de si se permiten o no coincidencias superpuestas.
– Sin paliativos
14 de mayo a las 16:36
pedro laurey
Una versión más corta. 😉
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
-
return haystack.split(Pattern.quote(needle), -1).length - 1;
si por ejemploneedle=":)"
– Sr_y_Sra_D
16 de diciembre de 2012 a las 16:01
-
@lOranger Sin el
,-1
arrojará coincidencias finales.– Peter Lawrey
28 de diciembre de 2012 a las 12:02
-
¡Ay, gracias, es bueno saberlo! Esto me enseñará a leer las líneas pequeñas en el javadoc…
– Laurent Grégoire
28 de diciembre de 2012 a las 12:05
-
¡Bonito! Pero solo incluye coincidencias que no se superponen, ¿no? Por ejemplo, hacer coincidir “aa” en “aaa” devolverá 1, no 2. Por supuesto, la inclusión de coincidencias superpuestas o no superpuestas es válida y depende de los requisitos del usuario (tal vez una bandera para indicar superposiciones de recuento, sí/no).
-Cornel Masson
26 de abril de 2013 a las 9:24
-
-1 .. intente ejecutar esto en “aaaa” y “aa”.. la respuesta correcta es 3, no 2.
– Kalyanaraman Santhanam
15 de septiembre de 2014 a las 6:06
incumplimiento de código
La última línea estaba creando un problema. lastIndex
nunca estaría en -1, por lo que habría un bucle infinito. Esto se puede solucionar moviendo la última línea de código al bloque if.
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while(lastIndex != -1){
lastIndex = str.indexOf(findStr,lastIndex);
if(lastIndex != -1){
count ++;
lastIndex += findStr.length();
}
}
System.out.println(count);
Vaquero
¿Realmente tienes que encargarte tú mismo del emparejamiento? Especialmente si todo lo que necesita es el número de ocurrencias, las expresiones regulares son más ordenadas:
String str = "helloslkhellodjladfjhello";
Pattern p = Pattern.compile("hello");
Matcher m = p.matcher(str);
int count = 0;
while (m.find()){
count +=1;
}
System.out.println(count);
-
Esto NO encuentra caracteres especiales, encontrará 0 recuentos para las cadenas a continuación:
String str = "hel+loslkhel+lodjladfjhel+lo"; Pattern p = Pattern.compile("hel+lo");
– ben
2 de febrero de 2014 a las 4:09
-
sí lo hará si expresa su expresión regular correctamente. prueba con
Pattern.compile("hel\\+lo");
el+
El signo tiene un significado especial en una expresión regular y debe escaparse.– Juan
2 de febrero de 2014 a las 9:42
-
Si lo que está buscando es tomar una cadena arbitraria y usarla como una coincidencia exacta con todos los caracteres especiales de expresión regular ignorados,
Pattern.quote(str)
¡es tu amigo!–Mike Furtak
10 de enero de 2015 a las 18:11
-
esto no funciona para “aaa” cuando str = “aaaaaa”. Hay 4 respuestas pero la tuya da 2
– Puján
29 de octubre de 2016 a las 12:02
-
Esta solución no funciona para este caso: str = “Esta es una cadena de prueba \\n\\r”, subStr = “\\r”, muestra 0 ocurrencias.
– Maksim Ovsianikov
1 de diciembre de 2017 a las 23:21
Estoy muy sorprendido de que nadie haya mencionado este trazador de líneas. Es simple, conciso y funciona un poco mejor que str.split(target, -1).length-1
public static int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
-
Esto NO encuentra caracteres especiales, encontrará 0 recuentos para las cadenas a continuación:
String str = "hel+loslkhel+lodjladfjhel+lo"; Pattern p = Pattern.compile("hel+lo");
– ben
2 de febrero de 2014 a las 4:09
-
sí lo hará si expresa su expresión regular correctamente. prueba con
Pattern.compile("hel\\+lo");
el+
El signo tiene un significado especial en una expresión regular y debe escaparse.– Juan
2 de febrero de 2014 a las 9:42
-
Si lo que está buscando es tomar una cadena arbitraria y usarla como una coincidencia exacta con todos los caracteres especiales de expresión regular ignorados,
Pattern.quote(str)
¡es tu amigo!–Mike Furtak
10 de enero de 2015 a las 18:11
-
esto no funciona para “aaa” cuando str = “aaaaaa”. Hay 4 respuestas pero la tuya da 2
– Puján
29 de octubre de 2016 a las 12:02
-
Esta solución no funciona para este caso: str = “Esta es una cadena de prueba \\n\\r”, subStr = “\\r”, muestra 0 ocurrencias.
– Maksim Ovsianikov
1 de diciembre de 2017 a las 23:21
Aquí está, envuelto en un método agradable y reutilizable:
public static int count(String text, String find) {
int index = 0, count = 0, length = find.length();
while( (index = text.indexOf(find, index)) != -1 ) {
index += length; count++;
}
return count;
}
Hicimos uno muy bueno en Udacity: usamos newSTR = str.replace(findStr, “”); y devolvió count = ((str.length() – newSTR.length())/findStr.length());
– SolarLunix
14/09/2015 a las 17:46
Pregunta similar para personajes: stackoverflow.com/q/275944/873282
– koppor
16/04/2017 a las 19:42
¿No desea tener en cuenta también el caso en que el prefijo de la cadena de búsqueda es su sufijo? En ese caso, no creo que ninguna de las respuestas sugeridas funcione. aquí es un ejemplo En ese caso, necesitaría un algoritmo más elaborado, como el Knuth Morris Pratt (KMP), que está codificado en el libro CLRS.
– Sid
25 de julio de 2017 a las 15:42
no se detiene para usted, porque después de alcanzar su condición de ‘detención’ (lastIndex == -1) lo reinicia incrementando el valor de lastIndex (lastIndex += findStr.length();)
– Legna
01/08/2017 a las 22:30
@Sid si quisiera ese comportamiento, simplemente podría incrementar lastIndex en solo 1 cada vez en lugar de findStr.length. En mi caso, por ejemplo, solo necesito saber si un personaje coincide o no, no me importa contar varias superposiciones. así que solo depende de cada caso de uso individual
– Adam Burley
30 de enero de 2021 a las 2:44