1

Tengo un problema, quiero contar las vocales, consonantes, y caracteres especiales de una oración en java, pero las vocales acentuadas me las cuenta como consonantes.

Este es mi código, está hecho en NetBeans:

    int vocales = 0, consonantes = 0, especial = 0, x = 0, espacios = 0;
    String frase;

    System.out.println("Proporciona una frase: ");
    frase = leerc.nextLine().toLowerCase();

    for (x = 0; x <= frase.length() - 1; x++) {
        
        consonantes++;

        if ((frase.charAt(x) == 'a') || (frase.charAt(x) == 'e')
                || (frase.charAt(x) == 'i') || (frase.charAt(x) == 'o')
                || (frase.charAt(x) == 'u') || (frase.charAt(x) == 'á')
                || (frase.charAt(x) == 'é') || (frase.charAt(x) == 'í')
                || (frase.charAt(x) == 'ó') || (frase.charAt(x) == 'ú')) {

            vocales++;
        }
        
        if ((frase.charAt(x) == ' ')){
            espacios++;
        }
        
        if ((frase.charAt(x) == '|') || (frase.charAt(x) == '!')
                || (frase.charAt(x) == '"') || (frase.charAt(x) == '#')
                || (frase.charAt(x) == '$') || (frase.charAt(x) == '&')
                || (frase.charAt(x) == '/') || (frase.charAt(x) == '(') 
                || (frase.charAt(x) == ')') || (frase.charAt(x) == '=') 
                || (frase.charAt(x) == '?') || (frase.charAt(x) == '¿') 
                || (frase.charAt(x) == '¡') || (frase.charAt(x) == '´')
                || (frase.charAt(x) == '¨') || (frase.charAt(x) == '+') 
                || (frase.charAt(x) == '*') || (frase.charAt(x) == '{') 
                || (frase.charAt(x) == '}') || (frase.charAt(x) == ',')
                || (frase.charAt(x) == ';') || (frase.charAt(x) == '.')
                || (frase.charAt(x) == ':') || (frase.charAt(x) == '>')
                || (frase.charAt(x) == '°')) {

            especial++;
        }

    }
    
    consonantes = consonantes - (vocales + especial + espacios);

    System.out.println("Número de vocales: " + vocales);
    System.out.println("Número de consonantes: " + consonantes);
    System.out.println("Número de caracteres especiales: " + especial);
TomuRain
  • 644
  • 4
  • 16

2 Answers2

0

Para evitar problemas podemos normalizar el texto de entrada a NFD con Normalizer la cual nos separa los acentos (sea: diéresis, acento grave, acento agudo, acento circunflejo , etc) en letra y acento.

"schön" ----NFD----> "scho\u0308n"

Para la solución

  1. Normalizamos el texto con Normalizer y reemplazamos los acentos con (replaceAll)
  2. Convertimos el texto a minúsculas
  3. Para cada caso reemplazamos lo que no sea lo que queremos de la cadena original y contamos los caracteres de la cadena
import java.text.Normalizer;
import java.util.Scanner;

public class Main {
    // Tiene el modificador private puesto que en este ejemplo sólo se usará en esta clase
    // Tanto scanner como el método son estáticos para que puedan ser accesados dentro del Main (otro contexto estático)
    private static Scanner leerc = new Scanner(System.in);
    private static String frase;

    public static void main(String[] args) {
        System.out.println("Proporciona una frase: ");
        // Se normaliza el texto con NFD y después se eliminan los caracteres en el
        // rango unicode del \u0300 al \u036f
        // también se convierte el texto a minúsculas
        frase = Normalizer.normalize(leerc.nextLine(), Normalizer.Form.NFD)
                .replaceAll("[\\u0300-\\u036f]", "")
                .toLowerCase();

        int consonantes, vocales, espacios, especial;

        // remplaza todo lo que sea diferente a espacios y calcula su longitud
        espacios = frase.replaceAll("[\\S]", "").length();
        // remplaza todo lo que sea diferente a una vocal (a, e, i, o, u)
        vocales = frase.replaceAll("[^aeiou]", "").length();
        // remplaza todo lo que no sea una letra y le resta las vocales
        consonantes = frase.replaceAll("[^a-zñ]", "").length() - vocales;
        // De tu cadena original se le restan los espacios, las vocales y las consonantes
        // Todo lo demás se considera especial
        especial = frase.length() - espacios - vocales - consonantes;

        System.out.println("Número de vocales: " + vocales);
        System.out.println("Número de consonantes: " + consonantes);
        System.out.println("Número de espacios: " + espacios);
        System.out.println("Número de caracteres especiales: " + especial);
    }

}
Eduardo Jiménez
  • 2,093
  • 2
  • 6
  • 26
0

Pero es que tu sumas si o si consonantes++ aun cuando el carácter actual sea una vocal normal a, o un espacio, etc... me explico?

Siguiendo al pie de la letra ese código debes re-estructurar las condiciones:

      if ((frase.charAt(x) == 'a') || (frase.charAt(x) == 'e')
            || (frase.charAt(x) == 'i') || (frase.charAt(x) == 'o')
            || (frase.charAt(x) == 'u') || (frase.charAt(x) == 'á')
            || (frase.charAt(x) == 'é') || (frase.charAt(x) == 'í')
            || (frase.charAt(x) == 'ó') || (frase.charAt(x) == 'ú')) {

        vocales++;
      } else if ((frase.charAt(x) == ' ')){
        espacios++;
      } else if ((frase.charAt(x) == '|') || (frase.charAt(x) == '!')
            || (frase.charAt(x) == '"') || (frase.charAt(x) == '#')
            || (frase.charAt(x) == '$') || (frase.charAt(x) == '&')
            || (frase.charAt(x) == '/') || (frase.charAt(x) == '(') 
            || (frase.charAt(x) == ')') || (frase.charAt(x) == '=') 
            || (frase.charAt(x) == '?') || (frase.charAt(x) == '¿') 
            || (frase.charAt(x) == '¡') || (frase.charAt(x) == '´')
            || (frase.charAt(x) == '¨') || (frase.charAt(x) == '+') 
            || (frase.charAt(x) == '*') || (frase.charAt(x) == '{') 
            || (frase.charAt(x) == '}') || (frase.charAt(x) == ',')
            || (frase.charAt(x) == ';') || (frase.charAt(x) == '.')
            || (frase.charAt(x) == ':') || (frase.charAt(x) == '>')
            || (frase.charAt(x) == '°')) {

        especial++;
      } else {
        //suma consonantes cuando NO es vocal, espacio o especial
        consonantes++;
      }

Ahora consonantes acumula la suma en base a un criterio lógico totalmente distinto; Eso en cuanto a la estructura lógica de la aplicación.

Nota Importante:

Mas allá que esa no sea la manera mas optima de abordar este problema, de todas formas hay que tener en cuenta que si el String contiene numeros o una @ o algún otro símbolo no especificado en las condiciones entonces los contará como consonantes!

JohnnyTB
  • 2,592
  • 1
  • 8
  • 17