Cómo comprobar si un número es primo en Java

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo comprobar si un número es primo en Java. Comenzaremos implementando un bucle básico para determinar la primalidad.

A continuación, optimizaremos el proceso de comprobación de números primos utilizando la raíz cuadrada del número. Finalmente, mejoraremos el código para manejar de manera adecuada las entradas negativas y no enteras.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java/BasicSyntaxGroup -.-> java/operators("Operators") java/BasicSyntaxGroup -.-> java/booleans("Booleans") java/BasicSyntaxGroup -.-> java/if_else("If...Else") java/BasicSyntaxGroup -.-> java/for_loop("For Loop") java/BasicSyntaxGroup -.-> java/while_loop("While Loop") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/user_input("User Input") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("Exceptions") java/SystemandDataProcessingGroup -.-> java/math_methods("Math Methods") subgraph Lab Skills java/operators -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/booleans -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/if_else -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/for_loop -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/while_loop -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/user_input -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/exceptions -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} java/math_methods -.-> lab-559969{{"Cómo comprobar si un número es primo en Java"}} end

Implementar un bucle básico de comprobación de números primos

En este paso, escribiremos un programa en Java para comprobar si un número dado es un número primo utilizando un bucle básico. Un número primo es un número natural mayor que 1 que no tiene divisores positivos distintos de 1 y él mismo.

  1. Abre el archivo HelloJava.java en el editor WebIDE si no está abierto.

  2. Reemplaza todo el contenido del archivo con el siguiente código:

    import java.util.Scanner;
    
    public class HelloJava {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            System.out.print("Enter a positive integer: ");
            int number = scanner.nextInt();
    
            if (number <= 1) {
                System.out.println(number + " is not a prime number.");
            } else {
                boolean isPrime = true;
                for (int i = 2; i < number; i++) {
                    if (number % i == 0) {
                        isPrime = false;
                        break; // Exit the loop early if a divisor is found
                    }
                }
    
                if (isPrime) {
                    System.out.println(number + " is a prime number.");
                } else {
                    System.out.println(number + " is not a prime number.");
                }
            }
    
            scanner.close();
        }
    }

    Entendamos las nuevas partes de este código:

    • Todavía usamos la clase Scanner para obtener la entrada del usuario.
    • int number = scanner.nextInt();: Esta línea lee un valor entero ingresado por el usuario y lo almacena en la variable number.
    • if (number <= 1): Comprobamos si el número es menor o igual a 1. Los números menores o iguales a 1 no se consideran primos.
    • boolean isPrime = true;: Introducimos una variable booleana llamada isPrime y la inicializamos en true. La usaremos para llevar un registro de si el número es primo.
    • for (int i = 2; i < number; i++): Este es un bucle for. Comienza con i en 2 y continúa mientras i sea menor que number. En cada iteración, i se incrementa en 1. Comenzamos a buscar divisores a partir de 2 porque 1 siempre es un divisor y estamos buscando divisores distintos de 1 y del número mismo.
    • if (number % i == 0): Dentro del bucle, esta línea comprueba si number es divisible exactamente por i (el residuo de la división es 0). Si lo es, significa que encontramos un divisor distinto de 1 y del número mismo.
    • isPrime = false;: Si se encuentra un divisor, establecemos isPrime en false.
    • break;: Esta declaración sale inmediatamente del bucle for. Una vez que encontramos un divisor, sabemos que el número no es primo, por lo que no es necesario seguir comprobando.
    • Finalmente, comprobamos el valor de isPrime para imprimir si el número es primo o no.
  3. Guarda el archivo (Ctrl+S o Cmd+S).

  4. Compila el programa modificado en la terminal:

    javac HelloJava.java

    Si no hay errores de compilación, se creará un archivo HelloJava.class.

  5. Ejecuta el programa compilado:

    java HelloJava
  6. El programa te pedirá que ingreses un número entero positivo. Ingresa un número (por ejemplo, 7) y presiona Enter. El programa te dirá si el número es primo o no. Intenta ingresar diferentes números como 4, 11, 1 o 0 para ver la salida.

    Enter a positive integer: 7
    7 is a prime number.
    Enter a positive integer: 4
    4 is not a prime number.

¡Has implementado con éxito un comprobador básico de números primos utilizando un bucle en Java!

Optimizar la comprobación de números primos con la raíz cuadrada

En el paso anterior, nuestro bucle de comprobación de números primos iteraba desde 2 hasta el número mismo. Aunque esto funciona, puede ser ineficiente para números muy grandes. Podemos optimizar esto comprobando solo los divisores hasta la raíz cuadrada del número.

He aquí por qué esta optimización funciona: Si un número n tiene un divisor d mayor que su raíz cuadrada (d > sqrt(n)), entonces debe haber otro divisor d' tal que d * d' = n. Este otro divisor d' debe ser menor que la raíz cuadrada (d' < sqrt(n)). Por lo tanto, si un número tiene algún divisor distinto de 1 y sí mismo, debe tener al menos un divisor menor o igual a su raíz cuadrada. Entonces, solo necesitamos comprobar los divisores hasta la raíz cuadrada.

  1. Abre el archivo HelloJava.java en el editor WebIDE.

  2. Modifica el bucle for en el método main para que itere solo hasta la raíz cuadrada del número. Reemplaza el bloque del bucle for existente con el siguiente código:

    // ... (código anterior) ...
    
    if (number <= 1) {
        System.out.println(number + " is not a prime number.");
    } else {
        boolean isPrime = true;
        // Optimize the loop to check up to the square root
        int limit = (int) Math.sqrt(number);
        for (int i = 2; i <= limit; i++) {
            if (number % i == 0) {
                isPrime = false;
                break; // Exit the loop early if a divisor is found
            }
        }
    
        if (isPrime) {
            System.out.println(number + " is a prime number.");
        } else {
            System.out.println(number + " is not a prime number.");
        }
    }
    
    // ... (resto del código) ...

    Veamos los cambios:

    • int limit = (int) Math.sqrt(number);: Calculamos la raíz cuadrada del number utilizando Math.sqrt(). Este método devuelve un double, así que lo convertimos a un int porque nuestro contador de bucle i es un entero. Almacenamos este valor en una variable llamada limit.
    • for (int i = 2; i <= limit; i++): El bucle ahora itera desde 2 hasta el limit calculado (la parte entera de la raíz cuadrada), inclusive.
  3. Guarda el archivo (Ctrl+S o Cmd+S).

  4. Compila el programa optimizado en la terminal:

    javac HelloJava.java

    Nuevamente, si no hay errores, se generará un archivo HelloJava.class.

  5. Ejecuta el programa compilado:

    java HelloJava
  6. Ingresa diferentes números para probar el comprobador de números primos optimizado. Deberías obtener los mismos resultados que antes, pero para números muy grandes, esta versión será más rápida.

    Enter a positive integer: 29
    29 is a prime number.
    Enter a positive integer: 100
    100 is not a prime number.

¡Has optimizado con éxito tu programa de comprobación de números primos reduciendo el número de iteraciones en el bucle!

Manejar entradas negativas y no enteras

En los pasos anteriores, nuestro programa asume que el usuario siempre ingresará un número entero positivo. Sin embargo, en aplicaciones del mundo real, los usuarios pueden ingresar números negativos, cero o incluso texto no entero. Nuestro programa actual no maneja estos casos de manera adecuada. En este paso, agregaremos comprobaciones para manejar entradas negativas y no enteras.

  1. Abre el archivo HelloJava.java en el editor WebIDE.

  2. Modifica el método main para incluir comprobaciones para números negativos y utiliza un bucle para asegurarte de que el usuario ingrese un número entero positivo válido. Reemplaza el código existente dentro del método main con lo siguiente:

    import java.util.Scanner;
    import java.util.InputMismatchException; // Import this class
    
    public class HelloJava {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int number = 0;
            boolean validInput = false;
    
            // Loop until valid positive integer input is received
            while (!validInput) {
                System.out.print("Enter a positive integer: ");
                try {
                    number = scanner.nextInt();
                    if (number > 0) {
                        validInput = true; // Input is valid, exit loop
                    } else {
                        System.out.println("Please enter a positive integer (greater than 0).");
                    }
                } catch (InputMismatchException e) {
                    System.out.println("Invalid input. Please enter an integer.");
                    scanner.next(); // Consume the invalid input to prevent infinite loop
                }
            }
    
            // Now, perform the prime check on the valid positive number
            if (number <= 1) { // This check is technically redundant now due to the input loop, but good for clarity
                System.out.println(number + " is not a prime number.");
            } else {
                boolean isPrime = true;
                int limit = (int) Math.sqrt(number);
                for (int i = 2; i <= limit; i++) {
                    if (number % i == 0) {
                        isPrime = false;
                        break;
                    }
                }
    
                if (isPrime) {
                    System.out.println(number + " is a prime number.");
                } else {
                    System.out.println(number + " is not a prime number.");
                }
            }
    
            scanner.close();
        }
    }

    Analicemos las nuevas adiciones:

    • import java.util.InputMismatchException;: Importamos esta clase para manejar casos en los que el usuario ingresa algo que no es un número entero.
    • int number = 0; boolean validInput = false;: Inicializamos number y una bandera booleana validInput.
    • while (!validInput): Este es un bucle while que seguirá ejecutándose mientras validInput sea false.
    • try { ... } catch (InputMismatchException e) { ... }: Este es un bloque try-catch. El código dentro del bloque try se ejecuta. Si ocurre una InputMismatchException (lo que significa que la entrada no era un número entero), se ejecuta el código dentro del bloque catch.
    • number = scanner.nextInt();: Intentamos leer un número entero.
    • if (number > 0): Dentro del bloque try, comprobamos si el número ingresado es positivo. Si lo es, establecemos validInput en true para salir del bucle.
    • System.out.println("Please enter a positive integer (greater than 0).");: Si el número no es positivo, mostramos un mensaje de error.
    • System.out.println("Invalid input. Please enter an integer.");: Dentro del bloque catch, si ocurre una InputMismatchException, mostramos un mensaje de error.
    • scanner.next();: Esto es crucial dentro del bloque catch. Consume la entrada no válida del scanner, evitando un bucle infinito en el que el programa sigue intentando leer la misma entrada no válida.
  3. Guarda el archivo (Ctrl+S o Cmd+S).

  4. Compila el programa actualizado:

    javac HelloJava.java
  5. Ejecuta el programa:

    java HelloJava
  6. Ahora, intenta ingresar diferentes tipos de entrada:

    • Ingresa un número entero positivo (por ejemplo, 13).
    • Ingresa un número entero negativo (por ejemplo, -5).
    • Ingresa cero (0).
    • Ingresa texto (por ejemplo, "hello").

    Observa cómo el programa maneja estas diferentes entradas, solicitándote que ingreses un número entero positivo válido hasta que lo hagas.

    Enter a positive integer: -5
    Please enter a positive integer (greater than 0).
    Enter a positive integer: 0
    Please enter a positive integer (greater than 0).
    Enter a positive integer: hello
    Invalid input. Please enter an integer.
    Enter a positive integer: 17
    17 is a prime number.

¡Has hecho con éxito que tu programa de comprobación de números primos sea más robusto al manejar números negativos y entradas no enteras utilizando un bucle y manejo de excepciones!

Resumen

En este laboratorio (lab), aprendimos cómo comprobar si un número es primo en Java. Comenzamos implementando una comprobación básica de números primos utilizando un bucle que itera desde 2 hasta el número menos uno, verificando la divisibilidad. Este enfoque inicial proporcionó una comprensión fundamental de la definición de número primo y su implementación algorítmica.

Luego exploramos optimizaciones para mejorar la eficiencia de la comprobación de números primos. Esto implicó entender que solo necesitamos comprobar los divisores hasta la raíz cuadrada del número, lo que reduce significativamente el número de iteraciones necesarias para entradas más grandes. Finalmente, abordamos casos extremos (edge cases) manejando números negativos y entradas no enteras para hacer que nuestra función de comprobación de números primos sea más robusta y completa.