Módulo 02: Algoritmos, pseudocódigo y diagramas de flujo

Objetivos del módulo

  • Aplicar un método para resolver problemas: entender, diseñar, implementar y probar
  • Conocer qué es un algoritmo y sus propiedades (finito, preciso y definido)
  • Identificar la entrada, el proceso y la salida de un problema
  • Escribir algoritmos en pseudocódigo en español, con las convenciones de PSeInt
  • Dibujar e interpretar diagramas de flujo con los símbolos normalizados
  • Comprobar algoritmos a mano con trazas (pruebas de escritorio)
  • Diseñar con la técnica de refinamiento sucesivo (top-down)
  • Traducir pseudocódigo a Java con una tabla de equivalencias
  • Resolver algoritmos clásicos: área, par/impar, mayor de dos y de tres números, suma de N números, tabla de multiplicar, factorial, número primo, MCD de Euclides y menús

1. Resolver problemas antes de programar

En el módulo 00 viste que el error más común al empezar es sentarse a teclear sin saber qué se va a escribir. Programar es, sobre todo, resolver problemas; escribir el código en Java es solo el último paso.

El matemático George Pólya propuso en 1945 un método para resolver problemas que se adapta perfectamente a la programación:

Fase Pregunta clave En programación
1. Entender el problema ¿Qué me piden? ¿Qué datos tengo? ¿Qué resultado debo obtener? Identificar entradas, salidas y reglas. Pensar en casos especiales
2. Diseñar un plan ¿Cómo paso de los datos al resultado? ¿He resuelto algo parecido? Escribir el algoritmo en pseudocódigo o con un diagrama de flujo
3. Ejecutar el plan ¿Cómo lo escribo en el lenguaje? Codificar en Java
4. Revisar ¿Funciona en todos los casos? ¿Se puede mejorar? Probar con trazas y con ejecuciones reales; corregir

💡 Consejo: Antes de escribir una sola línea, intenta resolver el problema tú mismo, a mano, con datos concretos. Si no sabes calcular a mano el máximo común divisor de 48 y 18, difícilmente sabrás explicarle al ordenador cómo hacerlo.

1.1. Un ejemplo de “entender el problema”

Enunciado: “Calcula el precio de una entrada de cine. La entrada normal cuesta 9 €; los menores de 12 años y los mayores de 65 pagan 6 €.”

Antes de diseñar nada, hazte preguntas:

  • ¿Qué datos necesito? La edad de la persona.
  • ¿Qué tengo que mostrar? El precio.
  • ¿Qué reglas hay? Si edad < 12 o edad > 65 → 6 €; en otro caso → 9 €.
  • ¿Casos límite? ¿Una persona de exactamente 12 años paga 6 € o 9 €? ¿Y una de 65? Según el enunciado, “menores de 12” no incluye al 12 y “mayores de 65” no incluye al 65: ambos pagan 9 €. Si hay dudas, se pregunta al cliente.
  • ¿Datos incorrectos? ¿Qué hacer con una edad negativa?

Este último tipo de preguntas es el que distingue a un buen programador.


2. ¿Qué es un algoritmo?

📘 Concepto: Un algoritmo es un conjunto finito y ordenado de instrucciones precisas que, a partir de unos datos de entrada, permite obtener una solución (salida) a un problema en un tiempo finito. La palabra viene del matemático persa del siglo IX al-Juarismi, cuyo nombre latinizado era Algoritmi.

2.1. Propiedades

Propiedad Significado Contraejemplo
Finito Termina después de un número finito de pasos “Mientras haya números naturales, escríbelos” (no acaba nunca)
Preciso Cada paso indica sin ambigüedad qué hacer y en qué orden “Añade un poco de sal” (¿cuánto es un poco?)
Definido Con los mismos datos de entrada produce siempre el mismo resultado “Elige un número cualquiera y súmale 2” (cada vez da algo distinto)

Además, todo algoritmo tiene:

  • Entrada: cero o más datos que recibe.
  • Salida: al menos un resultado. Un algoritmo que no produce nada no sirve para nada.
  • Eficacia: cada instrucción debe poder realizarse de verdad (no vale “averigua el número de la lotería de mañana”).

2.2. Entrada, proceso y salida

Casi todos los programas siguen el mismo esquema: reciben datos, los transforman y muestran resultados.

Esquema entrada-proceso-salida con el ejemplo del área de un rectángulo

Figura 1. Esquema entrada → proceso → salida.

Problema Entrada Proceso Salida
Área de un rectángulo base, altura area = base × altura area
Precio con IVA precio sin IVA final = precio × 1,21 precio final
Nota media nota1, nota2, nota3 media = (nota1 + nota2 + nota3) / 3 media
¿Es mayor de edad? edad comparar edad ≥ 18 “Sí” o “No”
Conversión de moneda euros, tipo de cambio dólares = euros × cambio dólares

✏️ Ejercicio: Identifica la entrada, el proceso y la salida de un programa que calcula cuántos segundos hay en un número de horas dado.

2.3. Formas de representar un algoritmo

Representación Ventajas Inconvenientes
Lenguaje natural (“primero pide la edad…”) Lo entiende cualquiera Ambiguo y extenso
Pseudocódigo Preciso, cercano al código, fácil de escribir y corregir Hay que aprender unas convenciones
Diagrama de flujo Muy visual; se ve el camino que sigue la ejecución Laborioso de dibujar y modificar; ocupa mucho en algoritmos grandes
Código en un lenguaje (Java) Se puede ejecutar Exige conocer la sintaxis y distrae del razonamiento

En este módulo usaremos las tres últimas para cada problema.


3. Pseudocódigo

📘 Concepto: El pseudocódigo es una forma de escribir algoritmos con palabras del lenguaje natural (en nuestro caso, español) pero siguiendo una estructura y unas palabras clave fijas, parecidas a las de un lenguaje de programación. No se ejecuta en un ordenador: sirve para pensar y comunicar la solución.

No existe un pseudocódigo “oficial”. En este curso usaremos las convenciones de PSeInt, una herramienta gratuita y en español muy usada en institutos y universidades que permite escribir el pseudocódigo, ejecutarlo paso a paso y generar automáticamente su diagrama de flujo. Todos los algoritmos de este módulo funcionan en PSeInt.

💡 Consejo: Descarga PSeInt (es gratuito, para Windows, macOS y Linux) y prueba en él los algoritmos de este módulo. En Configurar → Opciones del lenguaje puedes elegir un perfil más o menos estricto; con el perfil Estricto te obligará a declarar las variables con Definir, como hacemos aquí.

3.1. Estructura general

Algoritmo NombreDelAlgoritmo
    Definir variable1, variable2 Como Tipo
    // instrucciones
FinAlgoritmo

3.2. Tipos de datos

Tipo en pseudocódigo Qué guarda Ejemplos En Java (módulo 03)
Entero Números sin decimales 7, -3, 0 int
Real Números con decimales 3.14, -0.5 double
Caracter Texto (en PSeInt, una o varias letras) "A", "Hola" char / String
Logico Verdadero o falso Verdadero, Falso boolean

3.3. Instrucciones básicas

Instrucción Significado Ejemplo
Definir x Como Entero Declara una variable y su tipo Definir edad Como Entero
x <- expresión Asignación: calcula la expresión y guarda el resultado en x total <- precio * 1.21
Leer x Entrada: espera a que el usuario escriba un valor y lo guarda en x Leer edad
Escribir a, b Salida: muestra textos y valores en pantalla Escribir "Total: ", total
// texto Comentario // calculamos el IVA

⚠️ Importante: La flecha <- se lee “toma el valor de”. x <- x + 1 no es una ecuación imposible: significa “calcula x + 1 con el valor actual de x y guarda el resultado otra vez en x”. En Java se escribe con =, y la comparación de igualdad con ==.

3.4. Operadores

Tipo Pseudocódigo Significado Java
Aritméticos + - * / Suma, resta, multiplicación, división + - * /
  MOD (o %) Resto de la división entera: 7 MOD 3 = 1 %
  ^ Potencia: 2 ^ 3 = 8 Math.pow(2, 3)
Relacionales = <> < > <= >= Igual, distinto, menor, mayor, menor o igual, mayor o igual == != < > <= >=
Lógicos Y, O, NO Conjunción, disyunción, negación &&, \|\|, !
Funciones RC(x), ABS(x), TRUNC(x) Raíz cuadrada, valor absoluto, parte entera Math.sqrt, Math.abs, (int)

3.5. Estructuras de control

Recuerda el teorema de la programación estructurada (módulo 00): cualquier algoritmo se puede escribir combinando solo tres estructuras.

1. Secuencia: las instrucciones se ejecutan una detrás de otra, en orden.

2. Selección (decisión):

// Si simple
Si condición Entonces
    instrucciones
FinSi

// Si doble
Si condición Entonces
    instrucciones si se cumple
SiNo
    instrucciones si no se cumple
FinSi

// Selección múltiple
Segun variable Hacer
    1:
        instrucciones para el valor 1
    2, 3:
        instrucciones para los valores 2 o 3
    De Otro Modo:
        instrucciones para cualquier otro valor
FinSegun

3. Iteración (repetición):

// Mientras: comprueba la condición ANTES de cada vuelta (puede no ejecutarse nunca)
Mientras condición Hacer
    instrucciones
FinMientras

// Repetir: comprueba la condición DESPUÉS (se ejecuta al menos una vez)
Repetir
    instrucciones
Hasta Que condición

// Para: repite un número conocido de veces
Para i <- 1 Hasta 10 Con Paso 1 Hacer
    instrucciones
FinPara

⚠️ Importante: En Repetir ... Hasta Que condición, el bucle termina cuando la condición es verdadera. En Mientras condición, el bucle continúa mientras la condición es verdadera. Es una diferencia sutil que provoca muchos errores; en Java, el equivalente de Repetir es do { } while (condición), que continúa mientras la condición es verdadera, así que hay que negar la condición al traducirlo.

3.6. Buenas prácticas al escribir pseudocódigo

  • Usa nombres de variables significativos: precioTotal mejor que pt o x.
  • Sangra las instrucciones que están dentro de un Si, Mientras, Para…
  • Muestra un mensaje antes de cada Leer para que el usuario sepa qué tiene que escribir.
  • Un paso por línea.
  • Inicializa los contadores y acumuladores antes de los bucles.

4. Diagramas de flujo

📘 Concepto: Un diagrama de flujo (u ordinograma) es la representación gráfica de un algoritmo mediante símbolos normalizados unidos por líneas de flujo (flechas) que indican el orden de ejecución. Los símbolos están definidos por las normas ANSI e ISO 5807.

Tabla de símbolos de los diagramas de flujo: terminal, proceso, entrada/salida, decisión, subproceso, conectores, documento, entrada manual, pantalla, preparación y línea de flujo

Figura 2. Símbolos normalizados de los diagramas de flujo.

Símbolo Forma Uso
Terminal Óvalo / rectángulo redondeado Inicio y fin del algoritmo. Debe haber un único inicio
Proceso Rectángulo Asignaciones y cálculos: area ← base * altura
Entrada/salida Paralelogramo Leer y Escribir
Decisión Rombo Una condición con dos salidas, Sí y No (o una por cada valor en un Según)
Subproceso Rectángulo con dobles líneas laterales Llamada a un proceso definido en otro diagrama (lo que en Java será un método, módulo 07)
Conector Círculo Une dos puntos del diagrama en la misma página sin cruzar líneas
Conector de página Pentágono El diagrama continúa en otra página
Documento, entrada manual, pantalla Formas específicas Indican el dispositivo concreto (impresora, teclado, pantalla). En la práctica casi siempre se usa el paralelogramo genérico
Preparación Hexágono Algunos autores lo usan para el bucle Para
Línea de flujo Flecha Une los símbolos e indica el orden

Reglas para dibujarlos bien:

  1. El flujo va de arriba abajo y de izquierda a derecha.
  2. Las líneas son horizontales o verticales, sin cruzarse (usa conectores si hace falta).
  3. Cada símbolo tiene una sola flecha de entrada (los caminos se juntan antes de entrar) y una sola de salida, salvo el rombo, que tiene dos (o varias).
  4. Un único Inicio y un único Fin.
  5. El texto dentro de los símbolos debe ser breve.

💡 Consejo: Los diagramas de flujo son ideales para entender algoritmos pequeños y para ver los caminos de las decisiones y los bucles. Para algoritmos grandes, el pseudocódigo es mucho más práctico. PSeInt dibuja el diagrama de flujo de cualquier pseudocódigo con el botón Dibujar diagrama de flujo.


5. Trazas o pruebas de escritorio

📘 Concepto: Una traza (o prueba de escritorio) consiste en ejecutar el algoritmo a mano, con papel y lápiz, anotando en una tabla el valor de cada variable después de cada paso. Sirve para comprobar que el algoritmo hace lo que debe antes de programarlo, y para encontrar errores lógicos en programas que ya existen.

Cómo se hace:

  1. Haz una tabla con una columna por variable (y, si quieres, una para la condición y otra para la salida).
  2. Elige unos datos de prueba concretos.
  3. Ejecuta el algoritmo instrucción a instrucción, como si fueras el ordenador. Cada vez que una variable cambie, anota su nuevo valor en una fila nueva.
  4. Al final, comprueba que la salida es la esperada.

Ejemplo: traza del siguiente fragmento con n = 4:

suma <- 0
i <- 1
Mientras i <= n Hacer
    suma <- suma + i
    i <- i + 1
FinMientras
Escribir suma
Paso n i suma i <= n Salida
inicio 4 1 0    
vuelta 1 4 2 1 1 <= 4 → V  
vuelta 2 4 3 3 2 <= 4 → V  
vuelta 3 4 4 6 3 <= 4 → V  
vuelta 4 4 5 10 4 <= 4 → V  
salida 4 5 10 5 <= 4 → F 10

El algoritmo suma 1 + 2 + 3 + 4 = 10. ¡Correcto!

💡 Consejo: Elige los datos de prueba con cabeza: un caso normal, los casos límite (0, 1, el máximo, iguales…) y algún caso incorrecto (negativos, valores fuera de rango). La mayoría de errores se esconden en los límites.


6. Refinamiento sucesivo (diseño descendente)

Los problemas reales son demasiado grandes para resolverlos de un tirón. La técnica de refinamiento sucesivo o diseño descendente (top-down), propuesta por Niklaus Wirth en 1971, consiste en:

  1. Describir la solución con pocos pasos generales (nivel 0 y 1).
  2. Refinar cada paso, descomponiéndolo en pasos más concretos.
  3. Repetir hasta que cada paso sea una instrucción sencilla que se pueda traducir directamente al lenguaje de programación.

Árbol de refinamiento sucesivo para calcular la nota final de un alumno

Figura 3. Diseño descendente del problema “calcular la nota final de un alumno”.

Nivel 1:

1. Leer las notas
2. Calcular la nota final
3. Mostrar el resultado

Nivel 2 (refinamos cada paso; la nota final es el 60 % del examen y el 40 % de las prácticas):

1. Leer las notas
   1.1. Escribir "Nota del examen: " y Leer examen
   1.2. Escribir "Nota de prácticas: " y Leer practicas
2. Calcular la nota final
   2.1. nota <- examen * 0.6 + practicas * 0.4
3. Mostrar el resultado
   3.1. Escribir la nota
   3.2. Si nota >= 5, Escribir "Aprobado"; si no, Escribir "Suspenso"

Pseudocódigo final:

Algoritmo NotaFinal
    Definir examen, practicas, nota Como Real
    // 1. Leer las notas
    Escribir "Nota del examen: "
    Leer examen
    Escribir "Nota de prácticas: "
    Leer practicas
    // 2. Calcular la nota final
    nota <- examen * 0.6 + practicas * 0.4
    // 3. Mostrar el resultado
    Escribir "Nota final: ", nota
    Si nota >= 5 Entonces
        Escribir "Aprobado"
    SiNo
        Escribir "Suspenso"
    FinSi
FinAlgoritmo

En Java (fíjate en que los comentarios de los pasos del nivel 1 se conservan):

import java.util.Scanner;

public class NotaFinal {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);

        // 1. Leer las notas
        System.out.print("Nota del examen: ");
        double examen = teclado.nextDouble();
        System.out.print("Nota de prácticas: ");
        double practicas = teclado.nextDouble();

        // 2. Calcular la nota final (60 % examen, 40 % prácticas)
        double nota = examen * 0.6 + practicas * 0.4;

        // 3. Mostrar el resultado
        System.out.println("Nota final: " + nota);
        if (nota >= 5) {
            System.out.println("Aprobado");
        } else {
            System.out.println("Suspenso");
        }
    }
}

Ejecución con un 6 en el examen y un 9 en prácticas:

Nota del examen: 6
Nota de prácticas: 9
Nota final: 7.199999999999999
Aprobado

¿7.199999999999999 en lugar de 7.2? No es un error del algoritmo: es cómo guardan los ordenadores los números con decimales. Lo explicaremos en el módulo 03 y en el módulo 04 aprenderás a mostrarlo redondeado (7,20).

📘 Concepto: Cada paso del nivel 1 es un candidato natural a convertirse en un método (módulo 07): leerNotas(), calcularNotaFinal(), mostrarResultado(). El diseño descendente es la base de la programación modular.


7. De pseudocódigo a Java

Aunque todavía no conoces la sintaxis de Java (la irás aprendiendo en los módulos 03 a 06), esta tabla te muestra que la traducción es casi mecánica. Tenla a mano como referencia.

Pseudocódigo (PSeInt) Java Módulo
Algoritmo Nombre ... FinAlgoritmo public class Nombre { public static void main(String[] args) { ... } } 01
Definir x Como Entero int x; 03
Definir x Como Real double x; 03
Definir c Como Caracter String c; (o char c; para una sola letra) 03
Definir b Como Logico boolean b; 03
x <- 5 x = 5; 03
Escribir "Hola" System.out.println("Hola"); 04
Escribir Sin Saltar "Nombre: " System.out.print("Nombre: "); 04
Escribir "Total: ", t System.out.println("Total: " + t); 04
Leer x (entero) x = teclado.nextInt(); (con Scanner teclado = new Scanner(System.in);) 04
Leer x (real) x = teclado.nextDouble(); 04
a MOD b a % b 03
a = b (comparación) a == b 03
a <> b a != b 03
c1 Y c2 / c1 O c2 / NO c c1 && c2 / c1 \|\| c2 / !c 03
RC(x) / x ^ 2 Math.sqrt(x) / Math.pow(x, 2) 03
Si c Entonces ... SiNo ... FinSi if (c) { ... } else { ... } 05
Segun x Hacer 1: ... De Otro Modo: ... FinSegun switch (x) { case 1 -> ...; default -> ...; } 05
Mientras c Hacer ... FinMientras while (c) { ... } 06
Repetir ... Hasta Que c do { ... } while (!c); 06
Para i <- 1 Hasta n Con Paso 1 Hacer ... FinPara for (int i = 1; i <= n; i++) { ... } 06
Verdadero / Falso true / false 03

⚠️ Importante: Los tres errores de traducción más frecuentes: usar = para comparar (en Java es ==), olvidar negar la condición al pasar de Repetir ... Hasta Que a do ... while, y olvidar que en Java la división entre dos enteros descarta los decimales (7 / 2 da 3; módulo 03).

En los programas Java de este módulo leemos datos con la clase Scanner. Todavía no la hemos explicado (lo haremos en el módulo 04); de momento, copia esta “receta”:

import java.util.Scanner;                       // al principio del fichero

Scanner teclado = new Scanner(System.in);       // una vez, al principio de main
int n = teclado.nextInt();                      // leer un entero
double x = teclado.nextDouble();                // leer un número con decimales

💡 Consejo: Al ejecutar estos programas en un ordenador configurado en español, los números con decimales se escriben con coma (2,5), no con punto. Lo explicamos en el módulo 04.


8. Algoritmos resueltos

Para cada problema verás el análisis, el pseudocódigo, el diagrama de flujo, el programa en Java y una ejecución real. Las ejecuciones muestran lo que verías en la consola: los números que aparecen después de cada pregunta son los que escribe el usuario.

8.1. Área de un rectángulo (secuencia)

Análisis. Entrada: base y altura (reales). Proceso: area = base × altura. Salida: area.

Algoritmo AreaRectangulo
    Definir base, altura, area Como Real
    Escribir "Base: "
    Leer base
    Escribir "Altura: "
    Leer altura
    area <- base * altura
    Escribir "El área es ", area
FinAlgoritmo

Diagrama de flujo del área de un rectángulo: inicio, leer base y altura, calcular área, escribir área, fin

Figura 4. Diagrama de flujo del área de un rectángulo (estructura secuencial).

import java.util.Scanner;

public class AreaRectangulo {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);

        // Entrada
        System.out.print("Base: ");
        double base = teclado.nextDouble();
        System.out.print("Altura: ");
        double altura = teclado.nextDouble();

        // Proceso
        double area = base * altura;

        // Salida
        System.out.println("El área es " + area);
    }
}
Base: 5
Altura: 3
El área es 15.0

Es el ejemplo más simple de estructura secuencial: las instrucciones se ejecutan una tras otra, sin decisiones ni repeticiones.

8.2. ¿Par o impar? (decisión doble)

Análisis. Entrada: un entero n. Un número es par si el resto de dividirlo entre 2 es 0. Salida: “Par” o “Impar”.

Algoritmo ParImpar
    Definir n Como Entero
    Escribir "Introduce un número entero: "
    Leer n
    Si n MOD 2 = 0 Entonces
        Escribir n, " es par"
    SiNo
        Escribir n, " es impar"
    FinSi
FinAlgoritmo

Diagrama de flujo par o impar con una decisión n MOD 2 = 0

Figura 5. Diagrama de flujo de “¿par o impar?” (decisión doble).

import java.util.Scanner;

public class ParImpar {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Introduce un número entero: ");
        int n = teclado.nextInt();

        if (n % 2 == 0) {
            System.out.println(n + " es par");
        } else {
            System.out.println(n + " es impar");
        }
    }
}

Dos ejecuciones:

Introduce un número entero: 7
7 es impar
Introduce un número entero: -4
-4 es par

⚠️ Importante: Para saber si un número es impar, no compares n % 2 == 1: con números negativos, en Java -7 % 2 vale -1, no 1. Comprueba siempre n % 2 == 0 (par) o n % 2 != 0 (impar).

8.3. Mayor de dos números (decisiones anidadas)

Análisis. Entrada: dos enteros a y b. Hay tres casos posibles, no dos: a mayor, b mayor o iguales. Olvidar el tercer caso es un error típico.

Algoritmo MayorDos
    Definir a, b Como Entero
    Escribir "Primer número: "
    Leer a
    Escribir "Segundo número: "
    Leer b
    Si a > b Entonces
        Escribir "Mayor: ", a
    SiNo
        Si b > a Entonces
            Escribir "Mayor: ", b
        SiNo
            Escribir "Iguales"
        FinSi
    FinSi
FinAlgoritmo

Diagrama de flujo del mayor de dos números con dos decisiones anidadas

Figura 6. Diagrama de flujo del mayor de dos números.

import java.util.Scanner;

public class MayorDos {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Primer número: ");
        int a = teclado.nextInt();
        System.out.print("Segundo número: ");
        int b = teclado.nextInt();

        if (a > b) {
            System.out.println("Mayor: " + a);
        } else if (b > a) {
            System.out.println("Mayor: " + b);
        } else {
            System.out.println("Iguales");
        }
    }
}
Primer número: 8
Segundo número: 3
Mayor: 8
Primer número: 4
Segundo número: 4
Iguales

Observa que en Java el SiNo Si ... anidado se escribe de forma más compacta con else if.

8.4. Mayor de tres números

Análisis. Podríamos anidar muchas decisiones, pero hay una idea más elegante y que funciona con cualquier cantidad de números: suponer que el mayor es el primero y compararlo con cada uno de los demás, actualizándolo si encontramos uno mayor.

Algoritmo MayorTres
    Definir a, b, c, mayor Como Entero
    Escribir "Tres números: "
    Leer a, b, c
    mayor <- a
    Si b > mayor Entonces
        mayor <- b
    FinSi
    Si c > mayor Entonces
        mayor <- c
    FinSi
    Escribir "El mayor es ", mayor
FinAlgoritmo

Diagrama de flujo del mayor de tres números con la variable mayor y dos decisiones simples

Figura 7. Diagrama de flujo del mayor de tres números.

import java.util.Scanner;

public class MayorTres {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Tres números: ");
        int a = teclado.nextInt();
        int b = teclado.nextInt();
        int c = teclado.nextInt();

        int mayor = a;          // suponemos que el mayor es a
        if (b > mayor) {
            mayor = b;
        }
        if (c > mayor) {
            mayor = c;
        }
        System.out.println("El mayor es " + mayor);
    }
}
Tres números: 4 9 2
El mayor es 9

Traza con a = 4, b = 9, c = 2:

Instrucción a b c mayor Condición
Leer a, b, c 4 9 2    
mayor <- a 4 9 2 4  
Si b > mayor 4 9 2 9 9 > 4 → V
Si c > mayor 4 9 2 9 2 > 9 → F
Escribir         Salida: El mayor es 9

💡 Consejo: Con Scanner puedes escribir los tres números en la misma línea separados por espacios (4 9 2) o en líneas distintas: nextInt() lee el siguiente número esté donde esté.

8.5. Suma de N números (bucle Mientras con contador y acumulador)

Análisis. Entrada: n (cuántos números) y después los n números. Necesitamos dos variables especiales:

  • Un contador (i), que cuenta las vueltas: empieza en 1 y aumenta de 1 en 1.
  • Un acumulador (suma), que va sumando los números: empieza en 0 (el elemento neutro de la suma).
Algoritmo SumaN
    Definir n, i, num, suma Como Entero
    Escribir "¿Cuántos números vas a sumar? "
    Leer n
    suma <- 0
    i <- 1
    Mientras i <= n Hacer
        Escribir "Número ", i, ": "
        Leer num
        suma <- suma + num
        i <- i + 1
    FinMientras
    Escribir "La suma es ", suma
FinAlgoritmo

Diagrama de flujo de la suma de N números con un bucle mientras i <= n

Figura 8. Diagrama de flujo de la suma de N números (bucle con contador y acumulador).

En el diagrama se ve claramente el bucle: la flecha que sube desde i ← i + 1 y vuelve justo antes de la condición i <= n. Mientras la condición sea verdadera, se repite el cuerpo; cuando es falsa, se sale por la rama No.

import java.util.Scanner;

public class SumaN {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("¿Cuántos números vas a sumar? ");
        int n = teclado.nextInt();

        int suma = 0;
        int i = 1;
        while (i <= n) {
            System.out.print("Número " + i + ": ");
            int num = teclado.nextInt();
            suma = suma + num;
            i = i + 1;
        }
        System.out.println("La suma es " + suma);
    }
}
¿Cuántos números vas a sumar? 4
Número 1: 10
Número 2: 20
Número 3: 5
Número 4: 15
La suma es 50

Traza:

Momento n i num suma i <= n
antes del bucle 4 1   0 1 <= 4 → V
fin vuelta 1 4 2 10 10 2 <= 4 → V
fin vuelta 2 4 3 20 30 3 <= 4 → V
fin vuelta 3 4 4 5 35 4 <= 4 → V
fin vuelta 4 4 5 15 50 5 <= 4 → F

⚠️ Importante: Si olvidas i <- i + 1, la condición i <= n será siempre verdadera y el programa no terminará nunca: un bucle infinito. El algoritmo dejaría de ser finito. Si te pasa en la terminal, detén el programa con Ctrl+C; en IntelliJ, con el botón rojo ■ de la ventana Run.

8.6. Tabla de multiplicar (bucle Para)

Análisis. Entrada: un entero n. Salida: n x 1, n x 2… hasta n x 10. Sabemos de antemano cuántas vueltas hay que dar (10), así que el bucle natural es Para.

Algoritmo TablaMultiplicar
    Definir n, i Como Entero
    Escribir "¿Qué tabla quieres? "
    Leer n
    Para i <- 1 Hasta 10 Con Paso 1 Hacer
        Escribir n, " x ", i, " = ", n * i
    FinPara
FinAlgoritmo

Diagrama de flujo de la tabla de multiplicar con un bucle de i desde 1 hasta 10

Figura 9. Diagrama de flujo de la tabla de multiplicar. El bucle Para se dibuja con su inicialización, su condición y su incremento.

import java.util.Scanner;

public class TablaMultiplicar {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("¿Qué tabla quieres? ");
        int n = teclado.nextInt();

        for (int i = 1; i <= 10; i++) {
            System.out.println(n + " x " + i + " = " + (n * i));
        }
    }
}
¿Qué tabla quieres? 7
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

El for de Java reúne en una línea las tres partes del bucle que en el diagrama están separadas: inicialización (int i = 1), condición (i <= 10) e incremento (i++, que equivale a i = i + 1).

8.7. Factorial

Análisis. El factorial de n (se escribe n!) es el producto de todos los enteros desde 1 hasta n: 5! = 1 × 2 × 3 × 4 × 5 = 120. Por definición, 0! = 1. Es un acumulador de productos, que debe empezar en 1 (el elemento neutro de la multiplicación; si empezara en 0, el resultado sería siempre 0).

Algoritmo Factorial
    Definir n, i, f Como Entero
    Escribir "n = "
    Leer n
    f <- 1
    i <- 1
    Mientras i <= n Hacer
        f <- f * i
        i <- i + 1
    FinMientras
    Escribir n, "! = ", f
FinAlgoritmo

Diagrama de flujo del factorial con un acumulador f que empieza en 1

Figura 10. Diagrama de flujo del factorial.

import java.util.Scanner;

public class Factorial {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("n = ");
        int n = teclado.nextInt();

        long f = 1;             // long: el factorial crece muy deprisa
        int i = 1;
        while (i <= n) {
            f = f * i;
            i = i + 1;
        }
        System.out.println(n + "! = " + f);
    }
}
n = 5
5! = 120
n = 20
20! = 2432902008176640000

Traza con n = 5:

Vuelta i (al empezar) f ← f * i i (al terminar)
1 1 1 × 1 = 1 2
2 2 1 × 2 = 2 3
3 3 2 × 3 = 6 4
4 4 6 × 4 = 24 5
5 5 24 × 5 = 120 6
— 6 <= 5 es falso: sale    

💡 Consejo: El factorial crece tan rápido que con el tipo int (hasta unos 2 147 millones) solo puedes calcular hasta 12!. Por eso usamos long, que llega hasta 20!. En el módulo 03 verás qué ocurre cuando un número no cabe en su tipo (desbordamiento).

8.8. ¿Es primo?

Análisis. Un número es primo si es mayor que 1 y solo es divisible entre 1 y él mismo (2, 3, 5, 7, 11, 13…). Para comprobarlo, buscamos un divisor entre 2 y n - 1: si lo encontramos, no es primo.

Dos mejoras que hacen el algoritmo mucho más rápido:

  • Basta con probar divisores d mientras d × d <= n. Si n tuviera un divisor mayor que su raíz cuadrada, tendría también otro menor, que ya habríamos encontrado.
  • En cuanto encontramos un divisor, dejamos de buscar. Para eso usamos una variable lógica, una bandera (esPrimo), que forma parte de la condición del bucle.
Algoritmo Primo
    Definir n, d Como Entero
    Definir esPrimo Como Logico
    Escribir "Número: "
    Leer n
    esPrimo <- n >= 2
    d <- 2
    Mientras esPrimo Y d * d <= n Hacer
        Si n MOD d = 0 Entonces
            esPrimo <- Falso
        FinSi
        d <- d + 1
    FinMientras
    Si esPrimo Entonces
        Escribir n, " es primo"
    SiNo
        Escribir n, " no es primo"
    FinSi
FinAlgoritmo

Diagrama de flujo para saber si un número es primo con una bandera esPrimo y un bucle de divisores

Figura 11. Diagrama de flujo de “¿es primo?” con una bandera.

import java.util.Scanner;

public class Primo {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Número: ");
        int n = teclado.nextInt();

        boolean esPrimo = n >= 2;   // 0, 1 y los negativos no son primos
        int d = 2;
        while (esPrimo && d * d <= n) {
            if (n % d == 0) {
                esPrimo = false;    // hemos encontrado un divisor
            }
            d = d + 1;
        }

        if (esPrimo) {
            System.out.println(n + " es primo");
        } else {
            System.out.println(n + " no es primo");
        }
    }
}
Número: 29
29 es primo
Número: 21
21 no es primo

Traza con n = 21:

d esPrimo d * d <= n n MOD d Acción
2 V 4 <= 21 → V 1 no es divisor; d ← 3
3 V 9 <= 21 → V 0 ¡divisor! esPrimo ← F; d ← 4
4 F — — la condición esPrimo Y ... es falsa: sale

Con n = 29 se prueban d = 2, 3, 4, 5 (porque 6 × 6 = 36 > 29) y ninguno divide a 29: es primo. En lugar de 27 divisiones, solo 4.

8.9. Máximo común divisor: algoritmo de Euclides

Análisis. El MCD de dos números es el mayor número que divide a ambos. El algoritmo de Euclides (siglo III a. C.), uno de los algoritmos más antiguos que se conocen, se basa en que mcd(a, b) = mcd(b, a MOD b) y en que mcd(a, 0) = a. Se repite la sustitución hasta que el segundo número sea 0.

Algoritmo Mcd
    Definir a, b, r Como Entero
    Escribir "a = "
    Leer a
    Escribir "b = "
    Leer b
    Mientras b <> 0 Hacer
        r <- a MOD b
        a <- b
        b <- r
    FinMientras
    Escribir "MCD = ", a
FinAlgoritmo

Diagrama de flujo del algoritmo de Euclides con el bucle mientras b distinto de 0

Figura 12. Diagrama de flujo del algoritmo de Euclides.

import java.util.Scanner;

public class Mcd {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("a = ");
        int a = teclado.nextInt();
        System.out.print("b = ");
        int b = teclado.nextInt();

        while (b != 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        System.out.println("MCD = " + a);
    }
}
a = 48
b = 18
MCD = 6
a = 17
b = 5
MCD = 1

Traza con a = 48, b = 18:

Vuelta a b r ← a MOD b nuevo a nuevo b
1 48 18 48 MOD 18 = 12 18 12
2 18 12 18 MOD 12 = 6 12 6
3 12 6 12 MOD 6 = 0 6 0
— 6 0 b <> 0 es falso: sale    

Resultado: MCD = 6. Cuando el MCD de dos números es 1 (como 17 y 5), se dice que son primos entre sí.

📘 Concepto: Fíjate en el intercambio de valores: r ← a MOD b; a ← b; b ← r. El orden importa: si hicieras primero a ← b, perderías el valor original de a antes de usarlo. La variable r es una variable auxiliar.

8.10. Programa con menú (Repetir + Según)

Análisis. Muchos programas muestran un menú de opciones, ejecutan la elegida y vuelven a mostrarlo hasta que el usuario elige salir. Como el menú debe mostrarse al menos una vez, el bucle adecuado es Repetir ... Hasta Que, y para elegir la acción según la opción, Según.

Algoritmo Menu
    Definir op Como Entero
    Definir lado, r Como Real
    Repetir
        Escribir "1. Cuadrado  2. Círculo  0. Salir"
        Escribir Sin Saltar "Opción: "
        Leer op
        Segun op Hacer
            1:
                Escribir Sin Saltar "Lado: "
                Leer lado
                Escribir "Área = ", lado * lado
            2:
                Escribir Sin Saltar "Radio: "
                Leer r
                Escribir "Área = ", PI * r * r
            0:
                Escribir "Adiós"
            De Otro Modo:
                Escribir "Error: opción no válida"
        FinSegun
    Hasta Que op = 0
FinAlgoritmo

Diagrama de flujo de un programa con menú: escribir menú, leer opción, selección múltiple y repetir hasta que la opción sea 0

Figura 13. Diagrama de flujo de un programa con menú.

import java.util.Scanner;

public class Menu {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        int op;
        do {
            System.out.println("1. Cuadrado  2. Círculo  0. Salir");
            System.out.print("Opción: ");
            op = teclado.nextInt();
            switch (op) {
                case 1 -> {
                    System.out.print("Lado: ");
                    double lado = teclado.nextDouble();
                    System.out.println("Área = " + (lado * lado));
                }
                case 2 -> {
                    System.out.print("Radio: ");
                    double r = teclado.nextDouble();
                    System.out.println("Área = " + (Math.PI * r * r));
                }
                case 0 -> System.out.println("Adiós");
                default -> System.out.println("Error: opción no válida");
            }
        } while (op != 0);
    }
}
1. Cuadrado  2. Círculo  0. Salir
Opción: 1
Lado: 4
Área = 16.0
1. Cuadrado  2. Círculo  0. Salir
Opción: 2
Radio: 1
Área = 3.141592653589793
1. Cuadrado  2. Círculo  0. Salir
Opción: 5
Error: opción no válida
1. Cuadrado  2. Círculo  0. Salir
Opción: 0
Adiós

Observa la traducción del bucle: Hasta Que op = 0 (“termina cuando op es 0”) se convierte en while (op != 0) (“continúa mientras op no sea 0”). El switch con flechas -> lo estudiarás en detalle en el módulo 05.

8.11. Resumen de patrones

Los algoritmos anteriores contienen patrones que reutilizarás constantemente:

Patrón Idea Inicialización Ejemplo
Contador Variable que se incrementa en una cantidad fija i <- 0 o i <- 1 i <- i + 1
Acumulador de suma Va sumando valores suma <- 0 suma <- suma + num
Acumulador de producto Va multiplicando f <- 1 f <- f * i
Máximo/mínimo Supone que el primero es el mayor y lo compara con los demás mayor <- primero Si x > mayor Entonces mayor <- x
Bandera Variable lógica que indica si ha ocurrido algo encontrado <- Falso Si ... Entonces encontrado <- Verdadero
Intercambio Variable auxiliar para no perder un valor — aux <- a; a <- b; b <- aux
Menú Repetir + Según hasta elegir salir — Sección 8.10
Centinela Leer datos hasta un valor especial que indica el final Primera lectura antes del bucle Ejercicio 4

9. Errores frecuentes al diseñar algoritmos

Error Ejemplo Consecuencia Solución
No inicializar un acumulador suma <- suma + num sin suma <- 0 antes Resultado impredecible (en Java, error de compilación) Inicializa antes del bucle
Inicializar dentro del bucle suma <- 0 dentro del Mientras La suma se pone a cero en cada vuelta Inicializa fuera, antes del bucle
Olvidar actualizar la condición Falta i <- i + 1 Bucle infinito Comprueba que algo dentro del bucle acerca la condición a ser falsa
Error “por uno” Mientras i < n en lugar de i <= n Se hace una vuelta de menos (o de más) Traza con valores pequeños (n = 1, n = 2)
Olvidar casos Mayor de dos sin el caso “iguales” Respuesta incorrecta en ese caso Piensa en todos los casos posibles en el análisis
Confundir = de asignación y comparación En Java, if (a = b) Error de compilación Asignación =, comparación ==
Condición de Repetir sin negar Hasta Que op = 0 → while (op == 0) El bucle hace lo contrario while (op != 0)
Acumulador de producto en 0 f <- 0 para el factorial El resultado siempre es 0 Empieza en 1

10. Ejercicios

En cada ejercicio, escribe primero el pseudocódigo (y el diagrama de flujo si se pide), haz una traza con datos de prueba y, por último, tradúcelo a Java.

Ejercicio 1: Grados Celsius a Fahrenheit

Lee una temperatura en grados Celsius y muestra su equivalente en Fahrenheit. La fórmula es F = C × 9 / 5 + 32.

Ver solución

Es un algoritmo secuencial: entrada (celsius), proceso (fórmula) y salida (fahrenheit).

Algoritmo Temperatura
    Definir celsius, fahrenheit Como Real
    Escribir "Grados Celsius: "
    Leer celsius
    fahrenheit <- celsius * 9 / 5 + 32
    Escribir celsius, " ºC = ", fahrenheit, " ºF"
FinAlgoritmo
import java.util.Scanner;

public class Temperatura {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Grados Celsius: ");
        double celsius = teclado.nextDouble();
        double fahrenheit = celsius * 9 / 5 + 32;
        System.out.println(celsius + " ºC = " + fahrenheit + " ºF");
    }
}
Grados Celsius: 25
25.0 ºC = 77.0 ºF

Comprobación a mano: 25 × 9 = 225; 225 / 5 = 45; 45 + 32 = 77. Prueba también con 0 (debe dar 32), con 100 (212) y con −40 (curiosamente, −40 en ambas escalas).

Ejercicio 2: Descuento por compra

Una tienda aplica un 10 % de descuento a las compras de más de 100 €. Lee el importe y muestra el descuento aplicado y el total a pagar.

Ver solución

Usamos una decisión simple (sin SiNo): el descuento vale 0 salvo que se cumpla la condición.

Algoritmo Descuento
    Definir importe, descuento, total Como Real
    Escribir "Importe de la compra: "
    Leer importe
    descuento <- 0
    Si importe > 100 Entonces
        descuento <- importe * 0.10
    FinSi
    total <- importe - descuento
    Escribir "Descuento: ", descuento
    Escribir "Total a pagar: ", total
FinAlgoritmo
import java.util.Scanner;

public class Descuento {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Importe de la compra: ");
        double importe = teclado.nextDouble();

        double descuento = 0;
        if (importe > 100) {
            descuento = importe * 0.10;
        }
        double total = importe - descuento;

        System.out.println("Descuento: " + descuento);
        System.out.println("Total a pagar: " + total);
    }
}

Dos ejecuciones:

Importe de la compra: 150
Descuento: 15.0
Total a pagar: 135.0
Importe de la compra: 80
Descuento: 0.0
Total a pagar: 80.0

Caso límite: con exactamente 100 € no hay descuento, porque el enunciado dice “más de 100”. Si dijera “a partir de 100”, la condición sería importe >= 100.

Ejercicio 3: Calificación con texto

Lee una nota entera de 0 a 10 y muestra la calificación: Suspenso (0-4), Aprobado (5-6), Notable (7-8) o Sobresaliente (9-10). Si la nota está fuera de rango, muestra Nota no válida. Dibuja también el diagrama de flujo.

Ver solución

Encadenamos decisiones de forma que cada una solo se evalúa si las anteriores fueron falsas. Así no hace falta escribir nota >= 5 Y nota < 7: si llegamos a esa pregunta, ya sabemos que nota >= 5.

Algoritmo Calificacion
    Definir nota Como Entero
    Escribir "Nota (0-10): "
    Leer nota
    Si nota < 0 O nota > 10 Entonces
        Escribir "Nota no válida"
    SiNo
        Si nota < 5 Entonces
            Escribir "Suspenso"
        SiNo
            Si nota < 7 Entonces
                Escribir "Aprobado"
            SiNo
                Si nota < 9 Entonces
                    Escribir "Notable"
                SiNo
                    Escribir "Sobresaliente"
                FinSi
            FinSi
        FinSi
    FinSi
FinAlgoritmo

El diagrama de flujo es una “escalera” de cuatro rombos: cada rama Sí escribe una calificación y cada rama No baja al siguiente rombo; todas las ramas se juntan antes del Fin.

flowchart TD
    A([Inicio]) --> B[/"Leer nota"/]
    B --> C{"nota < 0 O nota > 10"}
    C -- Sí --> C1[/"Escribir 'Nota no válida'"/]
    C -- No --> D{"nota < 5"}
    D -- Sí --> D1[/"Escribir 'Suspenso'"/]
    D -- No --> E{"nota < 7"}
    E -- Sí --> E1[/"Escribir 'Aprobado'"/]
    E -- No --> F{"nota < 9"}
    F -- Sí --> F1[/"Escribir 'Notable'"/]
    F -- No --> F2[/"Escribir 'Sobresaliente'"/]
    C1 --> Z([Fin])
    D1 --> Z
    E1 --> Z
    F1 --> Z
    F2 --> Z
import java.util.Scanner;

public class Calificacion {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Nota (0-10): ");
        int nota = teclado.nextInt();

        if (nota < 0 || nota > 10) {
            System.out.println("Nota no válida");
        } else if (nota < 5) {
            System.out.println("Suspenso");
        } else if (nota < 7) {
            System.out.println("Aprobado");
        } else if (nota < 9) {
            System.out.println("Notable");
        } else {
            System.out.println("Sobresaliente");
        }
    }
}
Nota (0-10): 8
Notable

Datos de prueba recomendados: los límites de cada tramo (−1, 0, 4, 5, 6, 7, 8, 9, 10, 11).

Ejercicio 4: Media con valor centinela

Lee notas (números reales) hasta que el usuario escriba −1, y muestra cuántas notas se han introducido y su media. El −1 no cuenta como nota. Si no se introduce ninguna, muestra un aviso.

Ver solución

Un centinela es un valor especial que indica el fin de los datos. El patrón es: leer el primer dato antes del bucle, y dentro del bucle, procesar y leer el siguiente al final. Así, en cuanto se lee el centinela, la condición del Mientras lo detecta y no se procesa.

Algoritmo MediaCentinela
    Definir nota, suma Como Real
    Definir contador Como Entero
    suma <- 0
    contador <- 0
    Escribir "Nota (-1 para terminar): "
    Leer nota
    Mientras nota <> -1 Hacer
        suma <- suma + nota
        contador <- contador + 1
        Escribir "Nota (-1 para terminar): "
        Leer nota
    FinMientras
    Si contador > 0 Entonces
        Escribir "Media de ", contador, " notas: ", suma / contador
    SiNo
        Escribir "No se ha introducido ninguna nota"
    FinSi
FinAlgoritmo
import java.util.Scanner;

public class MediaCentinela {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        double suma = 0;
        int contador = 0;

        System.out.print("Nota (-1 para terminar): ");
        double nota = teclado.nextDouble();
        while (nota != -1) {
            suma = suma + nota;
            contador = contador + 1;
            System.out.print("Nota (-1 para terminar): ");
            nota = teclado.nextDouble();
        }

        if (contador > 0) {
            System.out.println("Media de " + contador + " notas: " + (suma / contador));
        } else {
            System.out.println("No se ha introducido ninguna nota");
        }
    }
}
Nota (-1 para terminar): 6
Nota (-1 para terminar): 8
Nota (-1 para terminar): 7
Nota (-1 para terminar): -1
Media de 3 notas: 7.0

¿Por qué comprobamos contador > 0? Porque si el usuario escribe −1 a la primera, suma / contador sería una división entre cero.

Ejercicio 5: Potencia por multiplicaciones sucesivas

Calcula base elevado a exponente (entero mayor o igual que 0) sin usar el operador de potencia, multiplicando la base tantas veces como indique el exponente.

Ver solución

Sabemos cuántas veces hay que repetir (el exponente), así que usamos un Para y un acumulador de producto que empieza en 1. Si el exponente es 0, el bucle no se ejecuta ninguna vez y el resultado es 1, que es correcto (cualquier número elevado a 0 es 1).

Algoritmo Potencia
    Definir base, exponente, resultado, i Como Entero
    Escribir "Base: "
    Leer base
    Escribir "Exponente (>= 0): "
    Leer exponente
    resultado <- 1
    Para i <- 1 Hasta exponente Con Paso 1 Hacer
        resultado <- resultado * base
    FinPara
    Escribir base, "^", exponente, " = ", resultado
FinAlgoritmo
import java.util.Scanner;

public class Potencia {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Base: ");
        int base = teclado.nextInt();
        System.out.print("Exponente (>= 0): ");
        int exponente = teclado.nextInt();

        long resultado = 1;
        for (int i = 1; i <= exponente; i++) {
            resultado = resultado * base;
        }
        System.out.println(base + "^" + exponente + " = " + resultado);
    }
}
Base: 2
Exponente (>= 0): 10
2^10 = 1024

Ejercicio 6: Suma de los dígitos

Lee un número entero positivo y muestra la suma de sus dígitos (para 4729: 4 + 7 + 2 + 9 = 22). Haz la traza.

Ver solución

El truco está en dos operaciones con enteros: n MOD 10 da el último dígito y n / 10 (división entera) elimina el último dígito. Repetimos mientras queden dígitos.

Algoritmo SumaDigitos
    Definir n, suma, digito Como Entero
    Escribir "Número entero positivo: "
    Leer n
    suma <- 0
    Mientras n > 0 Hacer
        digito <- n MOD 10
        suma <- suma + digito
        n <- TRUNC(n / 10)
    FinMientras
    Escribir "Suma de los dígitos: ", suma
FinAlgoritmo

(En PSeInt, / siempre da un resultado real; por eso usamos TRUNC para quedarnos con la parte entera. En Java, la división entre dos int ya es entera.)

import java.util.Scanner;

public class SumaDigitos {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Número entero positivo: ");
        int n = teclado.nextInt();

        int suma = 0;
        while (n > 0) {
            int digito = n % 10;   // último dígito
            suma = suma + digito;
            n = n / 10;            // quitamos el último dígito
        }
        System.out.println("Suma de los dígitos: " + suma);
    }
}
Número entero positivo: 4729
Suma de los dígitos: 22

Traza:

Vuelta n (al empezar) digito ← n MOD 10 suma n ← n / 10
1 4729 9 9 472
2 472 2 11 47
3 47 7 18 4
4 4 4 22 0
— 0 > 0 es falso: sale      

Ejercicio 7: Traza un algoritmo desconocido

Haz la traza de este programa sin ejecutarlo. ¿Qué muestra? ¿Qué calcula en general?

public class Traza {
    public static void main(String[] args) {
        int a = 3;
        int b = 0;
        int i = 1;
        while (i <= 4) {
            b = b + a * i;
            i = i + 1;
        }
        System.out.println("b = " + b + ", i = " + i);
    }
}
Ver solución
Vuelta i (al empezar) a * i b i (al terminar)
antes 1   0  
1 1 3 3 2
2 2 6 9 3
3 3 9 18 4
4 4 12 30 5
— 5 <= 4 es falso: sale      

Salida real:

b = 30, i = 5

En general, calcula a × (1 + 2 + 3 + 4) = 3 × 10 = 30: la suma de los cuatro primeros múltiplos de a. Fíjate en que, al salir del bucle, i vale 5, no 4: es el valor que hizo falsa la condición.

Ejercicio 8 (propuesto): Entrada de cine

Implementa el algoritmo de la sección 1.1: lee la edad y muestra el precio de la entrada (6 € para menores de 12 y mayores de 65; 9 € para el resto). Si la edad es negativa o mayor de 120, muestra un error. Escribe pseudocódigo, diagrama de flujo, una tabla con al menos 6 casos de prueba (incluidos los límites 11, 12, 65 y 66) y el programa en Java.

Ejercicio 9 (propuesto): Año bisiesto

Un año es bisiesto si es divisible entre 4, salvo que sea divisible entre 100, en cuyo caso solo es bisiesto si también es divisible entre 400. Escribe el algoritmo que lee un año y dice si es bisiesto. Pruébalo con 2024 (sí), 1900 (no), 2000 (sí) y 2026 (no).

Ejercicio 10 (propuesto): Contar positivos, negativos y ceros

Lee 10 números enteros y muestra cuántos son positivos, cuántos negativos y cuántos ceros. Usa un bucle Para y tres contadores.

Ejercicio 11 (propuesto): Divisores de un número

Lee un entero positivo y muestra todos sus divisores y cuántos hay. Por ejemplo, para 12: 1, 2, 3, 4, 6, 12 (6 divisores). Haz la traza con n = 12.

Ejercicio 12 (propuesto): Cajero con menú

Escribe un programa con menú que simule un cajero con un saldo inicial de 1000 €. Opciones: 1) Consultar saldo, 2) Ingresar dinero, 3) Retirar dinero (sin permitir que el saldo quede negativo), 0) Salir. Usa Repetir ... Hasta Que y Según. Dibuja el diagrama de flujo.

Ejercicio 13 (propuesto): Sucesión de Fibonacci

La sucesión de Fibonacci empieza por 0 y 1, y cada término es la suma de los dos anteriores: 0, 1, 1, 2, 3, 5, 8, 13… Lee n y muestra los n primeros términos. Pista: necesitarás dos variables para los dos últimos términos y el patrón de intercambio. Haz la traza para n = 7.


Resumen

Concepto Idea clave
Resolución de problemas Entender → diseñar → implementar → probar
Algoritmo Pasos finitos, precisos y definidos que resuelven un problema
Entrada-proceso-salida Datos que se reciben → transformación → resultados
Pseudocódigo Algoritmo, Definir, Leer, Escribir, <-, Si, Segun, Mientras, Repetir, Para
PSeInt Herramienta gratuita para escribir, ejecutar y dibujar pseudocódigo en español
Diagrama de flujo Terminal (óvalo), proceso (rectángulo), E/S (paralelogramo), decisión (rombo), flechas
Secuencia Instrucciones una tras otra
Selección Si ... Entonces ... SiNo ... FinSi, Segun ... FinSegun
Iteración Mientras (0 o más vueltas), Repetir ... Hasta Que (1 o más), Para (número conocido)
Traza Ejecución a mano anotando las variables en una tabla
Refinamiento sucesivo Descomponer de lo general a lo concreto (top-down)
Contador / acumulador i <- i + 1 / suma <- suma + x (inicializados antes del bucle)
Bandera Variable lógica que recuerda si algo ha ocurrido
Centinela Valor especial que marca el fin de los datos
Traducción a Java <- → =, = → ==, MOD → %, Y/O/NO → &&/\|\|/!, Repetir ... Hasta Que c → do { } while (!c)