Java repeated letter counter

Asked

Viewed 2,851 times

5

I made a method to count the repeated letters that are stored and ordered alphabetically within a list. The method is counting right but the bug is at the time of printing, it prints the letter and the amount of times it appears in the sentence correctly the problem is that it prints the same element in the same amount of times as your counter.

Ex:a:3 appears 3 times

He printa:a:3 to:3 to:3

Example phrase:"Make sure you get good grades!"

Method:

public void imprimir(){
    for(int i = 0; i < this.mensagem.size(); i++){
        int cont = 0;
        for(int y = 0; y < this.mensagem.size(); y++){
            if(mensagem.get(i) == mensagem.get(y)) cont++;
        }
        System.out.println(mensagem.get(i)+":"+cont);
    }
}  

Upshot:

!:1 to:3 to:3 to:3 b:1 and:1 i:1 n:1 the:2 the:2 r:1 s:3 s:3 s:3 t:2 t:2 v:1 ê:1

3 answers

8


Separate operations into two methods, one goes count and the other goes show, never do a single thing, in which case first the code has to sweep the entire text and calculate until finished to then show the result, also use structures to store each letter, example:

import java.util.HashMap;
import java.util.Map;
public class JavaApplication3 
{
    public static void main(String[] args) 
    {
        String s = "Vê se tira notas boas!";
        Map<String, Integer> map = contar(s.replace(" ", "").toLowerCase());
        Imprimir(map);
    }

    public static Map<String, Integer> contar(String frase)
    {        
        Map<String, Integer> map = new TreeMap<>();                
        for(char item : frase.toCharArray())
        {
            Integer s = map.get(String.valueOf(item));
            if (s != null)
            {
                map.put(String.valueOf(item), ++s);
            }
            else
            {
                map.put(String.valueOf(item), 1);
            }
        }
        return map;
    }

    public static void Imprimir(Map<String, Integer> items)
    {       
        for(Map.Entry<String, Integer> a : items.entrySet())
        {
            System.out.println(a.getKey() + ": " +  a.getValue());
        }    
    }    
}

AN ONLINE EXAMPLE

References

4

You can use the Collections of Java in your favor as follows:

public static void main(String[] args) {
  Map<String, Integer> ocorrencias;

  ocorrencias = contar("Vê se tira notas boas!");
  ocorrencias.forEach((chave, valor) -> System.out.print(chave + ":" + valor + " "));
}

private static Map<String, Integer> contar(String frase) {
  Map<String, Integer> resultado = new TreeMap<>(); // TreeMap para manter o Map ordenado pelas chaves
  List<String> ocorrencias;
  Set<String> letras;

  ocorrencias = Arrays.asList(frase.replace(" ", "").split("")); // Transforma a frase em uma lista que facilitará a contagem
  letras = new TreeSet<>(ocorrencias); // Pega as letras sem duplicidade 

  // Percorre o array de letras sem repetição contando as ocorrências
  letras.forEach((String letra) -> {
    resultado.put(letra, Collections.frequency(ocorrencias, letra));
  });

  return resultado;
}

The code above produces:

!:1 V:1 a:3 b:1 e:1 i:1 n:1 o:2 r:1 s:3 t:2 ê:1

The TreeSet does not allow duplicated values, being great for storing letters without repetition. So a Map is filled with the value counted by the method frequency.

See working on Ideone.com.


Observing: Note that your method counts uppercase, lowercase and accented as different letters. If you want accounts for occurrences that ignore accents, uppercase and lowercase, use a method that performs conversions before counting as follows:

private static Map<String, Integer> contar2(String frase) {
  String normalizado = Normalizer.normalize(frase, Normalizer.Form.NFD);
  String semAcentos = normalizado.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
  frase = semAcentos.toUpperCase();

  return contar(frase);
}

Which produces the following result (using the same main from before):

!:1 A:3 B:1 E:2 I:1 N:1 O:2 R:1 S:3 T:2 V:1

1

This is happening because every time you find a letter, you’re counting how many times it appears and prints. In his example, he finds the "a" 3 times, and in the 3 times, he counts how many has and prints.

You can create a map and before counting how many times the letter appears, check if it has already been counted. This way you make your code faster too, preventing it from doing the same job.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.