Je crée une méthode qui prend une chaîne spécifiée et compte le nombre de fois où chaque lettre consécutive apparaît.
Par exemple:
encoder ("aabbcc");
devrait donner la sortie 2 2 2, car il y a 2 lettres apparaissant dans l'ordre
Mon code était:
for(int i=0;i<word.length()-1;i++) {
int count=1;
if(i!=word.length()-1) {
//System.out.println(word.charAt(i));
//System.out.println(word.charAt(i+1));
try {
while(word.charAt(i)==word.charAt(i+1)) {
count++;
i++;
}
} catch (Exception e) {}
System.out.print(count+" ");
}
}
Mais il n'arrêtait pas de me donner une IndexOutOfBoundsException code> donc je viens d'ajouter un bloc try and catch mais je sais qu'il existe un meilleur moyen
7 Réponses :
Ne regardez pas en avant comme ceci word.charAt (i) == word.charAt (i + 1) car cela vous donne l'erreur. Au lieu de cela, vérifiez si la lettre à l'index i est la même que la lettre de l'itération précédente - et si c'est le cas - incrémentez le compteur.
Bienvenue dans SO. En général, si vous recevez une exception, vous devez déterminer pourquoi plutôt que d'ajouter une capture.
Une solution plus simple serait:
Deque<Integer> counts = new LinkedList<>();
for (int i = 0; i < word.length(); i++) {
if (i > 0 && word.charAt(i) == word.charAt(i - 1))
counts.addLast(count.removeLast() + 1);
else
counts.addLast(1);
}
À la fin de la boucle, i + 1 est hors limites.
Vous pouvez les compter comme ceci:
if(i > 0 && word.charAt(i) == word.charAt(i - 1))
Vous pouvez tester que i + 1 est inférieur à word.length () dans votre condition de boucle while . Vous pouvez également enregistrer word.length () dans une variable locale. Comme,
int len = word.length();
for (int i = 0; i < len - 1; i++) {
int count = 1;
while (i + 1 < len && word.charAt(i) == word.charAt(i + 1)) {
count++;
i++;
}
System.out.print(count + " ");
}
Une autre approche serait d'utiliser regex.
String str = "aabbccxa";
String result = Pattern.compile("(?<=(.))(?!\\1)")
.splitAsStream(str)
.map(e -> String.valueOf(e.length()))
.collect(Collectors.joining(" "));
System.out.println(result);
Comment ça marche:
Je pense que c'est une question de goût si c'est mieux que les autres réponses. Plus efficace qu'une simple boucle? Je pense que cela dépend aussi de l'entrée.
char=a, occurance=2 char=b, occurance=3 char=c, occurance=2 char=a, occurance=4
Vous pouvez les rassembler sur une carte et les imprimer. Cela imprime les chaînes réelles qui correspondent au décompte, mais il peut facilement être personnalisé comme vous le souhaitez.
String str = "aabbbbcccccdddddaaaaz";
Map<Integer, List<String>> freq = Arrays.stream(
str.replaceAll("(([a-z])\\2*)", "$1,").split(",")).filter(
a -> a.length() > 1).collect(
Collectors.groupingBy(String::length));
freq.forEach((k, v) -> System.out.println(k + " : " + v));
imprime ce qui suit.
2: [aa]
4: [bbbb, aaaa]
5: [ccccc, ddddd]
Cette ligne
catch (Exception e) {}n'est généralement pas une bonne chose à faire. Je supprimerais cette capture d'essai et corrigerais toutes les exceptions avec un flux d'application approprié.