Como já foi explicado, o operador deveria ser &&
em vez de ||
(você quer que o caractere seja diferente de “a” e diferente de “e” e diferente de “i” etc, mas vc está testando com “ou” - se a letra for, por exemplo, “e”, ela é diferente de “a” e só isso já faz entrar no if
, pois com o operador ||
basta que uma das condições seja verdadeira).
Mas ainda tem outro porém. Mesmo se eu fizer if (c != 'a' && c != 'e' && c != 'i' && c != 'o' && c != 'u')
, ainda sim tem casos que não vai contar corretamente. Isso porque, como o usuário pode digitar qualquer coisa, nada impede que digite, por exemplo, bc1
ou !@#
. E tanto o dígito 1
quanto os caracteres !@#
entrarão neste if
e serão considerados “consoantes”. O if
só funciona corretamente se a string tiver apenas letras, mas se tiver qualquer outro caractere, não funciona mais.
Em exercícios isso não costuma ser uma preocupação, já que geralmente esse tipo de coisa só é testada com textos válidos (no caso, contendo apenas letras). Mas acho importante se acostumar a pensar um pouco além do “caminho feliz” (aquele no qual todos os dados são válidos e vc não precisa se preocupar em validar nada). Todo programa que aceita entradas do usuário deve estar preparado para receber qualquer coisa e só deixar passar o que for válido.
Então primeiro você precisa ver se de fato é uma letra, para só depois excluir as vogais. Além disso, não precisa desse booleano verifica
, pois você pode usar a própria contagem para saber se encontrou as 3 consoantes consecutivas. Algo assim:
public static boolean isConsoante(char c) {
if ('A' <= c && c <= 'Z') { // se é letra maiúscula, converte para minúscula
c = Character.toLowerCase(c);
}
if ('a' <= c && c <= 'z') { // se é letra, verifica se é vogal
// se não for nenhuma das vogais, então é consoante
return c != 'a' && c != 'e' && c != 'i' && c != 'o' && c != 'u';
}
// se não entrou no if acima, não é letra, e portanto não é consoante
return false;
}
public static void main(String args[]) throws Exception {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for (int i = 0; i < n; i++) {
String nome = in.next();
int consoantesSeguidas = 0;
for (int j = 0; j < nome.length(); j++) {
if (isConsoante(nome.charAt(j))) {
consoantesSeguidas++;
if (consoantesSeguidas == 3) {
break;
}
} else {
consoantesSeguidas = 0;
}
}
if (consoantesSeguidas == 3) {
System.out.println(nome + " não é fácil");
} else {
System.out.println(nome + " é fácil");
}
}
}
Separei a lógica de verificar se é consoante em um método, acho que fica um pouco mais legível do que se estivesse tudo dentro do for
.
Se for para usar a regex que foi sugerida (que também tem o mesmo porém, de considerar 1@#!
como consoantes), precisaria de uma modificação:
Scanner in = new Scanner(System.in);
int n = in.nextInt();
// não esqueça de dar import em java.util.regex.Pattern e java.util.regex.Matcher
Matcher matcher = Pattern.compile("[a-z&&[^aeiou]]{3}", Pattern.CASE_INSENSITIVE).matcher("");
for (int i = 0; i < n; i++) {
String nome = in.next();
if (matcher.reset(nome).find()) {
System.out.println(nome + " não é fácil");
} else {
System.out.println(nome + " é fácil");
}
}
No caso, a expressão [a-z&&[^aeiou]]
pega todas as letras de “a” a “z”, exceto as vogais (claro que também poderia ser [bcdfghjklmnpqrstvwxyz]
, mas achei a primeira mais sucinta), e {3}
pega três ocorrências seguidas. A opção Pattern.CASE_INSENSITIVE
faz com que considere tanto letras maiúsculas quanto minúsculas.
Claro que também daria para usar nome.matches(...)
, a diferença é que este método compila a regex toda hora (sim, toda regex é compilada - não só em Java, mas em todas as linguagens que possuem este recurso - e convertida para uma estrutura interna). Já usando o Pattern
, a regex só é compilada uma vez e reaproveitada.
Novamente, vale ressaltar que em um exercício (no qual geralmente só se usam entradas válidas para testar) isso talvez não seja tão importante, pois provavelmente só vão testar com strings que contém apenas letras. Mas de qualquer forma fica a dica de sempre pensar um pouco além, principalmente se o programa recebe dados do usuário e que este pode digitar basicamente “qualquer coisa” (seja sem querer, seja de propósito).