2010-09-21 35 views
20

me gustaría contar las apariciones de un carácter en una cadena, supongamos que tengo la cadena "AAAAB", ¿cómo iba a contar que la cantidad de una que está en él?Encuentra ocurrencias de caracteres en una cadena de Java

+8

Parece que esta pregunta etiquetado con 'regex'. Recuerde, cuando se enfrentan con un problema, algunas personas piensan "¡Oye, usaré una expresión regular!" Ahora ellos tienen dos problemas. –

+0

@Greg Eso es solo un problema cuando la gente usa expresiones regulares [inadecuadamente] (http://betterwaytomakealiving.com/_wordpress/wp-content/uploads/2010/05/square-peg-round-hole.jpg) (como en esta pregunta) – NullUserException

+0

Bueno, cualquier solución estaría bien, pero estoy interesado en ver una en expresiones regulares también. –

Respuesta

13

El código parece mucho más fácil de leer si no utiliza expresiones regulares.

int count = 0; 
for(int i =0; i < string.length(); i++) 
    if(string.charAt(i) == 'a') 
     count++; 

count ahora contiene el número de 'a's en su cadena. Y, esto funciona en tiempo óptimo.

Las expresiones regulares son agradables para la coincidencia de patrones. Pero solo un ciclo regular hará el trabajo aquí.

+0

'jjnguy' Nelson: su respuesta (aceptada) solo funciona si planea contar javas de Java. No funciona para todos los caracteres Unicode que puede contener una cadena Java. String's * codePointAt (...) * es el método que está buscando, no * charAt (...) *, que está roto desde que salió Unicode 3.1. – SyntaxT3rr0r

+0

@Web ¿podría indicarme una referencia? Me interesaría aprender más. – jjnguy

+0

'jjnguy' Nelson: Creo que los JavaDoc son exhaustivos (no estoy seguro de lo dicho). Básicamente, * charAt * devuelve un valor de 16 bits y desde Unicode 3.1/Java 1.5 hay más de 65536 caracteres compatibles con Unicode (y Java). Por lo tanto, * charAt * puede devolver "algo" que no sea un carácter Unicode.El * codePointAt * más nuevo devuelve un valor de 32 bits y, por lo tanto, puede contener todos los caracteres Unicode válidos. – SyntaxT3rr0r

3

Un bucle simple a través de los personajes lo haría.

public int countChars(char c, String s) { 
    int result = 0; 
    for (int i = 0, n = s.length(); i < n; i++) { 
    if (s.charAt(i) == c) { 
     result++; 
    } 
    } 
    return result; 
} 
+0

FYI: cualquier JIT JRE decente lo hará mueva 'i

+0

Como patrón, este le impide pensar si la expresión limitante es algo que el compilador puede optimizar/es constante. Por ejemplo, escribiéndolo de esta manera, me ahorra tener que pensar si 'for (int i = 0; i dty

+0

Aunque estoy de acuerdo en este caso simple, no es necesario. – dty

15

Intente utilizar Apache Commons' StringUtils:

int count = StringUtils.countMatches("aaaab", "a"); 
// count = 4 
+0

Tenga en cuenta que StringUtils encontrará las ocurrencias de una Cadena dentro de otra Cadena, por lo que podría no ser tan eficiente como usar una búsqueda específica de caracteres. – dty

+1

+1 por brevedad y legibilidad –

+0

@MikeG, actualice el enlace: http://commons.apache.org/proper/commons-lang//apidocs/org/apache/commons/lang3/StringUtils.html –

4
int count = 0; 
for (char c : string.toCharArray()) 
    if (c == 'a') 
     count++; 
+0

¡Agradable y breve! Pero genera basura innecesaria. – dty

+0

¿Qué es "basura innecesaria"? –

+0

Al convertir el String en un char [] se asignará un nuevo carácter [] que se descartará tan pronto como termine el ciclo. – dty

22

CharMatcher API de guayaba es bastante potente y concisa:

CharMatcher.is('a').countIn("aaaab"); //returns 4 
+1

+1 para no reinventar la rueda – Nicramus

3

Aquí es una solución muy corto y sin ninguna bibliotecas adicionales:

String input = "aaaab"; 

int i = -1, count = 0; 
while((i = input.indexOf('a', i + 1)) != -1) count++; 

System.out.println(count); 
3

Las expresiones regulares no son particularmente buenas para contar cosas simples. Piensa en hormiga + almádena. Son buenos para romper cadenas complejas en pedazos.

De todos modos, aquí está uno solución de la OP está interesado en - usando una expresión regular para contar 'una de:

public class Reggie { 
    public static void main(String[] args) { 
     Pattern pattern = Pattern.compile("[^a]*a"); 
     Matcher matcher = pattern.matcher("aaabbbaaabbabababaaabbbbba"); 
     int count = 0; 
     while(matcher.find()) { 
      count++; 
     } 
     System.out.println(count+" matches"); 
    } 
} 

Esta es una manera bastante lento para hacerlo, como se ha señalado por otros. Peor aún, no es el más fácil y ciertamente no es el más probable que esté libre de errores. Sea como fuere, si querías algo un poco más complejo que 'a', la expresión regular se volvería más apropiada a medida que la cadena solicitada se volviera más compleja. Por ejemplo, si desea elegir cantidades en dólares de una cadena larga, una expresión regular podría ser la mejor respuesta.

Ahora, sobre la expresión regular: 'cero o más no' a' [^a]*a

Este [^a]* medios caracteres. Esto nos permite devorar crud no 'a' desde el comienzo de una cadena: si la entrada es 'bbba' entonces [^a]* coincidirá con 'bbb'. No coincide con la 'a'. No se preocupe, la 'a' en la expresión regular dice "coincida exactamente con 'a'". Así que nuestra expresión regular dice "coinciden cero o más caracteres que no son 'a' seguidos de 'a'".

Ok. Ahora puedes leer sobre Pattern y Matcher. La conclusión es que el Patrón es una expresión regular compilada. Es costoso compilar una expresión regular así que hago que la mía sea estática para que solo se compilen una vez. El Matcher es una clase que aplicará una cadena a un Patrón para ver si coincide. Matcher tiene información de estado que le permite rastrear una cadena aplicando un Patrón repetidamente.

El bucle básicamente dice: "matcher, se arrastran en la cadena de mí encontrar la siguiente ocurrencia del patrón. Si lo encontramos, incrementar el contador." Tenga en cuenta que las secuencias de caracteres que encuentra Matcher no son solo 'a'. Está encontrando secuencias como las siguientes: 'a', 'bbba', 'bba', 'ba', etc. Es decir, cadenas que no contienen una 'a' excepto su último carácter.

21
String string = "aaab"; 
int count = string.length() - string.replaceAll("a", "").length(); 

en lugar de "a" usar una expresión regular como "[a-zA-Z]" para contar todos los caracteres de palabra

+0

+1 para una solución simple –

+0

+1 para líneas simples – javadba

1

Usted puede simplemente utilizar esto:

String a = "i am here as junior java programmer"; 
Set temp = new HashSet(); 
char[] chararray=a.toCharArray(); 
Set temp=new HashSet(); 
for(int i=0;i<chararray.length;i++) 
{ 
    int count=0; 
    for (int j=0;j<chararray.length;j++) { 
     if (chararray[i]==chararray[j]) { 
      count++; 
     }    
    } 
    if (temp.add(chararray[i])!=false) 
     System.out.println("Character "+chararray[i]+" occur "+count); 

} 
+1

Parece innecesariamente complejo. Un solo bucle sobre los personajes debería hacerlo. Además, esta pregunta es bastante antigua. Lo mejor es no revivir los hilos viejos a menos que la respuesta agregue una mejora significativa a las respuestas anteriores. – Leigh

3
 String searchFor = "a"; 
     String base = "aaaab"; 
     int count=0; 
     int index =base.indexOf(searchFor); 

     while(index!=-1){ 
      ++count; 
      index = base.indexOf(searchFor, index+searchFor.length()); 
     } 

     System.out.println(count); 
2
public static void main(String[] args) { 

    Map<Character, Integer> data = new HashMap<Character, Integer>(); 

    String s = "aaaab"; 

    char[] chars = s.toCharArray(); 
    for (char a : chars) { 

     if (data.containsKey(a)) { 
      int value = data.get(a); 
      data.put(a, value + 1); 
     } else { 
      data.put(a, 1); 
     } 

    } 
    Iterator it = data.entrySet().iterator(); 
    while (it.hasNext()) { 
     Map.Entry pairs = (Map.Entry) it.next(); 
     System.out.println(pairs.getKey() + " = " + pairs.getValue()); 
    } 
} 
+0

¿Qué contiene la información? y ¿cómo es que containsKey funcionará? – Kumaran

1
String s1="parasanna"; 

StringBuffer sb=new StringBuffer(); 
boolean print = false; 
for (int i=0; i<s1.length(); i++){ 
    int count=1; 
    char c=s1.charAt(i); 
    sb.append(c); 
    for (int j=1; j<sb.length(); j++) { 
     char c2=sb.charAt(j-1); 
     if (c==c2) { 
      count++; 
     } 
    } 

    System.out.println(c+"=="+count); 

} 
1

Aquí está mi lógica ...

public class OccurenceOf_Character { 

    public static void main(String[] args) { 

     Scanner input=new Scanner(System.in);  
     System.out.println(" Enter a string"); 

     String str = input.nextLine();  
     System.out.println(" Enter a character");  

     String character=input.next();  
     int l = character.length(); 

     char c=character.charAt(0); 

     int count=0;   
     for(int i=0;i<str.length();i++) 
     { 
      if(str.charAt(i) == c) 
      { 
       count=count+1; 
      } 
     } 

     System.out.println(count); 
    } 
} 
0
public static void main(String[] args) throws IOException 
    { 
     //String s1="parasanna"; 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     System.out.println("enter string:"); 
     String s1 = br.readLine(); 
     StringBuffer sb=new StringBuffer(s1); 

     while(sb.length() != 0) 
     { 
      char c = sb.charAt(0); 
      int cnt = 0; 
      for(int i=0; i< sb.length(); i++) 
      { 
      if(c == sb.charAt(i)) 
      { 
       cnt++; 
       sb.deleteCharAt(i); 
       i--; 
      } 

      } 

      System.out.println(c + "  occurance is:" + cnt); 
     } 

    } 
1

Se puede utilizar la clase StringUtils proporcionada por apache commons. StringUtils.countMatches (String originalString, Cadena subCharacterSequesnce)

+0

Esto ya ha sido [sugerido] (http://stackoverflow.com/a/3764010/20938). –

1

Java 8

Enfoque 1 - Obtiene la ocurrencia de un solo carácter

String sentence = "Aaron ate apples upon a rock"; 

    long counted = IntStream.range(0, sentence.length()) 
      .filter(i->sentence.charAt(i) == 'a') 
      .count(); 
    System.out.println("First approach: " + counted); 

Enfoque 2 - permite que el personaje para ser especificado

String sentence = "Aaron ate apples upon a rock"; 

    BiFunction<String, Character, Long> counter = (s,c) -> { 
     return IntStream.range(0, s.length()) 
       .filter(i->s.charAt(i) == c) 
       .count(); 
    }; 
    System.out.println("Second approach (with 'a'): " + counter.apply(sentence, 'a')); 
    System.out.println("Second approach (with 'o'): " + counter.apply(sentence, 'o')); 

Enfoque 3 - Cuenta las ocurrencias de todos los personajes

 String sentence = "Aaron ate apples upon a rock"; 

    Map<Character, Long> counts = IntStream.range(0, sentence.length()) 
      .mapToObj(i->sentence.charAt(i)) 
      .collect(Collectors.groupingBy(o->o, Collectors.counting()));  

    System.out.println("Third approach for every character... "); 
    counts.keySet().stream() 
     .forEach(key -> System.out.println("'" + key + "'->" + counts.get(key))); 
Cuestiones relacionadas