length - string[] java
¿Cómo cuento el número de ocurrencias de un personaje en una cadena? (30)
Tengo la cuerda
a.b.c.d
Quiero contar las ocurrencias de ''.'' de una manera idiomática, preferiblemente de una sola línea.
(Anteriormente, había expresado esta restricción como "sin bucle", en caso de que se esté preguntando por qué todos intentan responder sin usar un bucle).
¿Por qué no simplemente dividir en el carácter y luego obtener la longitud de la matriz resultante? la longitud de la matriz siempre será el número de instancias + 1. ¿Verdad?
Aquí hay una solución de recursión de estilo ligeramente diferente:
public static int countOccurrences(String haystack, char needle)
{
return countOccurrences(haystack, needle, 0);
}
private static int countOccurrences(String haystack, char needle, int accumulator)
{
if (haystack.length() == 0) return accumulator;
return countOccurrences(haystack.substring(1), needle, haystack.charAt(0) == needle ? accumulator + 1 : accumulator);
}
Aquí hay una solución sin un bucle:
public static int countOccurrences(String haystack, char needle, int i){
return ((i=haystack.indexOf(needle, i)) == -1)?0:1+countOccurrences(haystack, needle, i+1);}
System.out.println("num of dots is "+countOccurrences("a.b.c.d",''.'',0));
Bueno, hay un bucle, pero es invisible :-)
- Yonatan
Con java-8 también puedes usar streams para lograr esto. Obviamente, hay una iteración detrás de escena, ¡pero no tienes que escribirlo explícitamente!
public static long countOccurences(String s, char c){
return s.chars().filter(ch -> ch == c).count();
}
countOccurences("a.b.c.d", ''.''); //3
countOccurences("hello world", ''l''); //3
De acuerdo, inspirado en la solución de Yonatan, aquí hay uno que es puramente recursivo: los únicos métodos de biblioteca utilizados son length()
y charAt()
, ninguno de los cuales hace bucles:
public static int countOccurrences(String haystack, char needle)
{
return countOccurrences(haystack, needle, 0);
}
private static int countOccurrences(String haystack, char needle, int index)
{
if (index >= haystack.length())
{
return 0;
}
int contribution = haystack.charAt(index) == needle ? 1 : 0;
return contribution + countOccurrences(haystack, needle, index+1);
}
El hecho de que la recursión cuente como bucle depende de la definición exacta que use, pero probablemente sea lo más cercano que pueda obtener.
No sé si la mayoría de las JVM hacen una recursión de cola en estos días ... si no, obtendrás el desbordamiento de pila del mismo nombre para cadenas adecuadamente largas, por supuesto.
El siguiente código fuente le dará un no. De ocurrencias de una cadena dada en una palabra ingresada por el usuario:
import java.util.Scanner;
public class CountingOccurences {
public static void main(String[] args) {
Scanner inp= new Scanner(System.in);
String str;
char ch;
int count=0;
System.out.println("Enter the string:");
str=inp.nextLine();
while(str.length()>0)
{
ch=str.charAt(0);
int i=0;
while(str.charAt(i)==ch)
{
count =count+i;
i++;
}
str.substring(count);
System.out.println(ch);
System.out.println(count);
}
}
}
En algún lugar del código, algo tiene que hacer un bucle. La única forma de evitar esto es un desenrollamiento completo del bucle:
int numDots = 0;
if (s.charAt(0) == ''.'') {
numDots++;
}
if (s.charAt(1) == ''.'') {
numDots++;
}
if (s.charAt(2) == ''.'') {
numDots++;
}
... etc, pero entonces usted es el que hace el bucle, manualmente, en el editor de origen, en lugar de la computadora que lo ejecutará. Ver el pseudocódigo:
create a project
position = 0
while (not end of string) {
write check for character at position "position" (see above)
}
write code to output variable "numDots"
compile program
hand in homework
do not think of the loop that your "if"s may have been optimized and compiled to
En caso de que estés usando Spring framework, también podrías usar la clase "StringUtils". El método sería "countOccurrencesOf".
Inspirado por Jon Skeet, una versión sin bucle que no hará explotar tu stack. También es un punto de partida útil si desea utilizar el marco fork-join.
public static int countOccurrences(CharSequeunce haystack, char needle) {
return countOccurrences(haystack, needle, 0, haystack.length);
}
// Alternatively String.substring/subsequence use to be relatively efficient
// on most Java library implementations, but isn''t any more [2013].
private static int countOccurrences(
CharSequence haystack, char needle, int start, int end
) {
if (start == end) {
return 0;
} else if (start+1 == end) {
return haystack.charAt(start) == needle ? 1 : 0;
} else {
int mid = (end+start)>>>1; // Watch for integer overflow...
return
countOccurrences(haystack, needle, start, mid) +
countOccurrences(haystack, needle, mid, end);
}
}
(Descargo de responsabilidad: No probado, no compilado, no sensible.)
Quizás la mejor manera de escribirlo (un solo subproceso, sin soporte de par sustituto):
public static int countOccurrences(String haystack, char needle) {
int count = 0;
for (char c : haystack.toCharArray()) {
if (c == needle) {
++count;
}
}
return count;
}
La forma más sencilla de obtener la respuesta es la siguiente:
public static void main(String[] args) {
String string = "a.b.c.d";
String []splitArray = string.split("//.");
System.out.println("No of . chars is : " + splitArray.length-1);
}
Mi ''una línea idiomática'' para esto es:
int count = StringUtils.countMatches("a.b.c.d", ".");
¿Por qué escribirlo tú mismo cuando ya está en commg lang ?
El oneliner de Spring Framework para esto es:
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
Mi solución ''idiomática de una sola línea'':
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
No tengo idea de por qué se acepta una solución que utiliza StringUtils.
No estoy seguro de la eficiencia de esto, pero es el código más corto que podría escribir sin incluir las librerías de terceros:
public static int numberOf(String target, String content)
{
return (content.split(target).length - 1);
}
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.
for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))
hace el truco, sin asignaciones adicionales que necesitan recopilación, en 1 línea o menos, solo con J2SE.
Puede usar la función split()
en un solo código de línea
int noOccurence=string.split("#").length-1;
Qué tal esto. No usa la expresión regular por debajo, por lo que debería ser más rápido que algunas de las otras soluciones y no utilizará un bucle.
int count = line.length() - line.replace(".", "").length();
Resuma otra respuesta y lo que sé, todas las formas de hacer esto usando una sola línea:
String testString = "a.b.c.d";
1) Utilizando Apache Commons
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
2) Usando Spring Framework''s
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
3) usando reemplazar
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
4) Utilizando replaceAll (caso 1)
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
5) Utilizando replaceAll (caso 2)
int replaceAllCase2 = testString.length() - testString.replaceAll("//.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
6) Usando split
int split = testString.split("//.",-1).length-1;
System.out.println("split = " + split);
7) Utilizando Java8 (caso 1)
long java8 = testString.chars().filter(ch -> ch ==''.'').count();
System.out.println("java8 = " + java8);
8) Usar Java8 (caso 2), puede ser mejor para Unicode que el caso 1
long java8Case2 = testString.codePoints().filter(ch -> ch ==''.'').count();
System.out.println("java8 (second case) = " + java8Case2);
9) Utilizando StringTokenizer
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);
Del comentario : Tenga cuidado con el StringTokenizer, porque abcd funcionará, pero para ... bc ... d o ... abcd or a ... b ...... c ..... d ... o etc. no funcionará. Sólo contará para. entre personajes solo una vez
Más información en github
github (usando JMH , mode = AverageTime, puntuación de 0.010
mejor que 0.351
):
Benchmark Mode Cnt Score Error Units
1. countMatches avgt 5 0.010 ± 0.001 us/op
2. countOccurrencesOf avgt 5 0.010 ± 0.001 us/op
3. stringTokenizer avgt 5 0.028 ± 0.002 us/op
4. java8_1 avgt 5 0.077 ± 0.005 us/op
5. java8_2 avgt 5 0.078 ± 0.003 us/op
6. split avgt 5 0.137 ± 0.009 us/op
7. replaceAll_2 avgt 5 0.302 ± 0.047 us/op
8. replace avgt 5 0.303 ± 0.034 us/op
9. replaceAll_1 avgt 5 0.351 ± 0.045 us/op
Si bien los métodos pueden ocultarlo, no hay forma de contar sin un bucle (o recursión). Desea utilizar un char [] por razones de rendimiento sin embargo.
public static int count( final String s, final char c ) {
final char[] chars = s.toCharArray();
int count = 0;
for(int i=0; i<chars.length; i++) {
if (chars[i] == c) {
count++;
}
}
return count;
}
El uso de replaceAll (es decir, RE) no parece ser la mejor manera de hacerlo.
También es posible utilizar reducir en Java 8 para resolver este problema:
int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == ''$'' ? 1 : 0));
System.out.println(res);
Salida:
3
Tarde o temprano, algo tiene que hacer un bucle. Es mucho más simple para usted escribir el bucle (muy simple) que usar algo como split
que es mucho más poderoso de lo que necesita.
Por supuesto, encapsule el bucle en un método separado, por ejemplo,
public static int countOccurrences(String haystack, char needle)
{
int count = 0;
for (int i=0; i < haystack.length(); i++)
{
if (haystack.charAt(i) == needle)
{
count++;
}
}
return count;
}
Entonces no necesita tener el bucle en su código principal, pero el bucle tiene que estar allí en algún lugar.
Tuve una idea similar a Mladen, pero al contrario ...
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
Un ejemplo más corto es
String text = "a.b.c.d";
int count = text.split("//.",-1).length-1;
Usando las colecciones de Eclipse
int count = CharAdapter.adapt("a.b.c.d").count(c -> c == ''.'');
Si tiene más de un carácter para contar, puede usar un CharBag
siguiente manera:
CharBag bag = CharAdapter.adapt("a.b.c.d").toBag();
int count = bag.occurrencesOf(''.'');
Nota: Soy un comendador de Eclipse Collections.
Muestra completa:
public class CharacterCounter
{
public static int countOccurrences(String find, String string)
{
int count = 0;
int indexOf = 0;
while (indexOf > -1)
{
indexOf = string.indexOf(find, indexOf + 1);
if (indexOf > -1)
count++;
}
return count;
}
}
Llamada:
int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("//.", "").length();
ReplaceAll (".") Reemplazaría a todos los caracteres.
La solución de PhiLho utiliza ReplaceAll ("[^.]", ""), Que no necesita escaparse, ya que [.] Representa el carácter ''punto'', no ''cualquier carácter''.
String s = "a.b.c.d";
long result = s.chars().filter(ch -> ch == ''.'').count();
String[] parts = text.split(".");
int occurances = parts.length - 1;
" It''s a great day at O.S.G. Dallas! "
-- Famous Last Words
Bueno, es un caso de conocer tu Java, especialmente tu comprensión básica de las clases de colección que ya están disponibles en Java. Si te fijas en la publicación completa aquí, hay casi todo menos que la explicación de Stephen Hawking sobre El origen del universo, el libro de bolsillo de Darwin sobre Evolución y la selección del elenco de Gene Roddenberry Star Trek sobre por qué se fueron con William Shatner sin saber cómo hacerlo. esto rápida y fácilmente ...
... necesito decir más?
import java.util.Scanner;
class apples {
public static void main(String args[]) {
Scanner bucky = new Scanner(System.in);
String hello = bucky.nextLine();
int charCount = hello.length() - hello.replaceAll("e", "").length();
System.out.println(charCount);
}
}// COUNTS NUMBER OF "e" CHAR´s within any string input
int count = (line.length() - line.replace("str", "").length())/"str".length();
public static int countOccurrences(String container, String content){
int lastIndex, currIndex = 0, occurrences = 0;
while(true) {
lastIndex = container.indexOf(content, currIndex);
if(lastIndex == -1) {
break;
}
currIndex = lastIndex + content.length();
occurrences++;
}
return occurrences;
}