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.
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 + 1no es una ecuación imposible: significa “calculax + 1con el valor actual dexy guarda el resultado otra vez enx”. 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. EnMientras condición, el bucle continúa mientras la condición es verdadera. Es una diferencia sutil que provoca muchos errores; en Java, el equivalente deRepetiresdo { } 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:
precioTotalmejor queptox. - Sangra las instrucciones que están dentro de un
Si,Mientras,Para… - Muestra un mensaje antes de cada
Leerpara 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.
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:
- El flujo va de arriba abajo y de izquierda a derecha.
- Las líneas son horizontales o verticales, sin cruzarse (usa conectores si hace falta).
- 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).
- Un único Inicio y un único Fin.
- 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:
- Haz una tabla con una columna por variable (y, si quieres, una para la condición y otra para la salida).
- Elige unos datos de prueba concretos.
- 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.
- 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:
- Describir la solución con pocos pasos generales (nivel 0 y 1).
- Refinar cada paso, descomponiéndolo en pasos más concretos.
- Repetir hasta que cada paso sea una instrucción sencilla que se pueda traducir directamente al lenguaje de programación.
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 deRepetir ... Hasta Queado ... while, y olvidar que en Java la división entre dos enteros descarta los decimales (7 / 2da3; 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
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
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 % 2vale-1, no1. Comprueba siempren % 2 == 0(par) on % 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
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
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
Scannerpuedes 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
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óni <= nserá 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
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
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 hasta12!. Por eso usamoslong, que llega hasta20!. 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
dmientrasd × d <= n. Sintuviera 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
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
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 primeroa ← b, perderías el valor original deaantes de usarlo. La variableres 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
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) |