Algoritmos, pseudocódigo y diagramas de flujo
En esta lección
Antes de escribir una sola línea de Java conviene aprender a pensar la solución: decidir qué pasos hay que dar y en qué orden. En esta lección aprenderás qué es un algoritmo, cómo escribirlo en pseudocódigo y en un diagrama de flujo, cómo convertirlo en Java y cómo comprobar a mano que funciona con una traza. Terminarás con cuatro ejemplos clásicos que aparecen en todos los exámenes de programación.
Nota: en esta lección verás código Java con variables,
ify bucles que todavía no conoces a fondo. No te preocupes: lo importante ahora es la lógica. Cada instrucción tiene su lección propia más adelante.
Qué es un algoritmo
Un algoritmo es una lista de pasos ordenados, precisos y finitos que resuelve un problema. Una receta de cocina o las instrucciones para montar un mueble son algoritmos.
Cada paso debe ser preciso (“echa un poco de sal” no vale para un ordenador; “echa 5 gramos” sí), el orden importa (no puedes freír el huevo antes de cascarlo) y el algoritmo tiene que terminar en algún momento.
Todo algoritmo tiene tres partes:
| Parte | Qué es | Ejemplo: calcular el precio con IVA |
|---|---|---|
| Entrada | Los datos que recibe | El precio sin IVA |
| Proceso | Las operaciones que hace | Multiplicar por 1,21 |
| Salida | El resultado que devuelve | El precio final |
Las tres estructuras básicas
Cualquier algoritmo se construye combinando solo tres bloques: secuencia (pasos uno detrás de otro), decisión (“si llueve, coge el paraguas”) y repetición (“mientras quede ropa en el cesto, tiende una prenda”). En Java se corresponden con instrucciones normales, con las condicionales y con los bucles.
Pseudocódigo
El pseudocódigo es una forma de escribir un algoritmo en lenguaje natural, pero con una estructura parecida a la de un programa. No tiene reglas oficiales; su ventaja es que te deja pensar la solución sin preocuparte de la sintaxis (puntos y coma, llaves, tipos).
Este es el pseudocódigo para calcular el precio de una compra con IVA:
INICIO
LEER precio
total ← precio * 1.21
ESCRIBIR total
FIN
La flecha ← significa asignar: guarda el valor de la derecha en la variable de la izquierda (un nombre que guarda un dato).
Con una decisión, el pseudocódigo para saber si un alumno ha aprobado sería:
INICIO
LEER nota
SI nota >= 5 ENTONCES
ESCRIBIR "Aprobado"
SINO
ESCRIBIR "Suspenso"
FIN SI
FIN
La sangría (lo de dentro del SI va desplazado) muestra de un vistazo qué pasos dependen de la condición.
Diagramas de flujo
Un diagrama de flujo representa el algoritmo con dibujos unidos por flechas. Cada forma tiene un significado:
| Forma | Uso |
|---|---|
| Óvalo | Inicio y fin |
| Paralelogramo | Entrada o salida de datos (leer, escribir) |
| Rectángulo | Proceso: un cálculo o una asignación |
| Rombo | Decisión: una pregunta con dos salidas, sí y no |
| Flechas | El orden en que se recorren los pasos |
El algoritmo del aprobado, dibujado con texto, quedaría así:
( INICIO )
|
v
/ LEER nota /
|
v
< ¿nota >= 5? >
| |
sí no
| |
v v
/ "Aprobado" / / "Suspenso" /
| |
+----+----+
|
v
( FIN )
Un bucle se dibuja como una flecha que vuelve hacia atrás hasta un rombo. Los diagramas son muy visuales para algoritmos cortos, pero con algoritmos largos se vuelven enormes; por eso en la práctica se usa más el pseudocódigo. En FP es habitual que te pidan los dos.
Consejo: para dibujarlos basta papel y lápiz o una herramienta gratuita como draw.io. En un examen cuenta que las formas sean las correctas y que ningún camino quede sin terminar.
De pseudocódigo a Java
Pasar un pseudocódigo bien escrito a Java es casi una traducción palabra por palabra:
| Pseudocódigo | Significado | Java |
|---|---|---|
x ← 5 | Guardar un valor | int x = 5; o x = 5; |
ESCRIBIR x | Mostrar por pantalla | System.out.println(x); |
LEER x | Pedir un dato | Un Scanner |
SI ... ENTONCES ... SINO ... FIN SI | Decisión | if (...) { } else { } |
MIENTRAS ... HACER ... FIN MIENTRAS | Repetir mientras se cumpla | while (...) { } |
PARA i DESDE 1 HASTA n | Repetir n veces | for (int i = 1; i <= n; i++) { } |
Para no complicar los ejemplos, los datos de entrada irán escritos directamente en el código.
Ejemplo 1: el mayor de tres números
Problema: dados tres números, mostrar el mayor.
La idea: supón que el primero es el mayor y compáralo con los otros dos. Si alguno es mayor, pasa a ser el nuevo “mayor”.
INICIO
LEER a, b, c
mayor ← a
SI b > mayor ENTONCES
mayor ← b
FIN SI
SI c > mayor ENTONCES
mayor ← c
FIN SI
ESCRIBIR mayor
FIN
En Java:
public class MayorDeTres {
public static void main(String[] args) {
int a = 14;
int b = 31;
int c = 27;
int mayor = a;
if (b > mayor) {
mayor = b;
}
if (c > mayor) {
mayor = c;
}
System.out.println("El mayor es " + mayor);
}
}
// El mayor es 31
Frente a la típica cadena de if (a > b && a > c)..., esta idea escala: con un bucle sirve para el mayor de cualquier cantidad de números, como verás en arrays.
Comprobar un algoritmo: la traza
Una traza (o prueba de escritorio) consiste en ejecutar el algoritmo a mano, paso a paso, apuntando en una tabla el valor de cada variable. Es la mejor forma de encontrar fallos.
La traza del mayor de tres con a = 14, b = 31, c = 27:
| Paso | Instrucción | mayor | Comentario |
|---|---|---|---|
| 1 | mayor ← a | 14 | |
| 2 | ¿b > mayor? → ¿31 > 14? | 14 | Sí, entra |
| 3 | mayor ← b | 31 | |
| 4 | ¿c > mayor? → ¿27 > 31? | 31 | No, no entra |
| 5 | ESCRIBIR mayor | 31 | Sale 31 |
Haz siempre trazas con varios casos, incluidos los raros: el mayor en primera o última posición, dos iguales, negativos…
Consejo: en los exámenes es habitual que te den un trozo de código y te pregunten qué muestra. La traza en una tabla es la forma de responder sin equivocarte.
Ejemplo 2: el factorial
Problema: calcular el factorial de un número n, que es el producto de todos los enteros desde 1 hasta n. Se escribe n!. Por ejemplo, 5! = 1 × 2 × 3 × 4 × 5 = 120.
Aquí hace falta un acumulador: una variable que empieza con un valor neutro y a la que en cada vuelta del bucle se le “añade” algo. Para multiplicar, el valor neutro es 1 (si empezaras en 0, todo daría 0).
En pseudocódigo: resultado ← 1 y luego PARA i DESDE 2 HASTA n HACER resultado ← resultado * i. En Java:
public class Factorial {
public static void main(String[] args) {
int n = 5;
long resultado = 1;
for (int i = 2; i <= n; i++) {
resultado = resultado * i;
}
System.out.println(n + "! = " + resultado);
}
}
// 5! = 120
La traza con n = 5:
| Vuelta | i | resultado antes | resultado después |
|---|---|---|---|
| 1 | 2 | 1 | 2 |
| 2 | 3 | 2 | 6 |
| 3 | 4 | 6 | 24 |
| 4 | 5 | 24 | 120 |
| — | 6 | — | Sale del bucle: 6 no es <= 5 |
Usamos long porque el factorial crece muy deprisa (13! ya no cabe en un int). Con n = 0 el bucle no da ninguna vuelta y sale 1, que es correcto. También se puede calcular con recursividad.
Ejemplo 3: ¿es primo?
Problema: saber si un número es primo, es decir, si solo se puede dividir de forma exacta entre 1 y él mismo. El 7 es primo; el 9 no, porque 9 entre 3 da exacto.
La idea: prueba a dividir entre 2, 3, 4… Si alguna división es exacta, no es primo. Y no hace falta llegar hasta n - 1: si n tiene un divisor mayor que su raíz cuadrada, tiene otro menor, así que basta con probar mientras d × d <= n. Para 91 solo hay que probar hasta 9, no hasta 90.
Para saber si una división es exacta se usa el resto: en Java, el operador % (en pseudocódigo suele escribirse MOD). Lo escribimos como un método que devuelve true o false (los verás en métodos); en cuanto encuentra un divisor, return false termina sin seguir probando:
public class Primo {
static boolean esPrimo(int n) {
if (n < 2) {
return false;
}
for (int d = 2; d * d <= n; d++) {
if (n % d == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(esPrimo(29));
System.out.println(esPrimo(91));
System.out.println(esPrimo(1));
}
}
// true
// false
// false
La traza de esPrimo(91):
d | d * d <= 91 | 91 % d | Qué pasa |
|---|---|---|---|
| 2 | 4, sí | 1 | Sigue |
| 3 | 9, sí | 1 | Sigue |
| 4 | 16, sí | 3 | Sigue |
| 5 | 25, sí | 1 | Sigue |
| 6 | 36, sí | 1 | Sigue |
| 7 | 49, sí | 0 | Divisor encontrado: devuelve false |
91 parece primo, pero es 7 × 13: no te fíes de la intuición.
Ejemplo 4: la suma de los dígitos
Problema: sumar las cifras de un número. Para 4073, el resultado es 4 + 0 + 7 + 3 = 14.
El truco está en dos operaciones con el número 10:
numero % 10da la última cifra (el resto de dividir entre 10):4073 % 10 = 3.numero / 10quita la última cifra (división entera, sin decimales):4073 / 10 = 407.
Repetimos (MIENTRAS numero > 0) hasta que el número se quede en 0:
public class SumaDigitos {
public static void main(String[] args) {
int numero = 4073;
int suma = 0;
while (numero > 0) {
int ultimo = numero % 10;
suma = suma + ultimo;
numero = numero / 10;
}
System.out.println("Suma de dígitos: " + suma);
}
}
// Suma de dígitos: 14
| Vuelta | numero al empezar | ultimo | suma | numero al terminar |
|---|---|---|---|---|
| 1 | 4073 | 3 | 3 | 407 |
| 2 | 407 | 7 | 10 | 40 |
| 3 | 40 | 0 | 10 | 4 |
| 4 | 4 | 4 | 14 | 0 |
Con el mismo esquema puedes contar cifras, invertir un número (4073 → 3704) o comprobar si es capicúa.
Cómo descomponer un problema
Para los ejercicios largos se usa el diseño descendente: partir el problema en subproblemas, y estos en otros más pequeños, hasta que cada uno sea fácil.
Imagina este enunciado: “Tenemos los minutos que ha entrenado una persona en el gimnasio cada día de la semana (0 si no fue). Muestra cuántos días entrenó, la media de minutos por sesión y el día en que más entrenó.”
Antes de programar, descompón:
Informe semanal del gimnasio
├── Contar días entrenados → recorrer y contar los que son > 0
├── Media por sesión → sumar todo y dividir entre los días entrenados
│ (¡cuidado si son 0!)
└── Mejor día → buscar la posición del máximo
y traducirla a nombre (0 = lunes...)
Cada rama es un problema pequeño que ya sabes resolver. En Java, cada una se convierte en un método con un nombre claro:
public class Gimnasio {
public static void main(String[] args) {
int[] minutos = {45, 0, 60, 30, 0, 90, 20};
System.out.println("Días entrenados: " + contarDiasActivos(minutos));
System.out.println("Media por sesión: " + mediaSesion(minutos) + " min");
}
static int contarDiasActivos(int[] minutos) {
int dias = 0;
for (int m : minutos) {
if (m > 0) {
dias++;
}
}
return dias;
}
static double mediaSesion(int[] minutos) {
int total = 0;
for (int m : minutos) {
total += m;
}
int dias = contarDiasActivos(minutos);
return dias == 0 ? 0 : (double) total / dias;
}
}
// Días entrenados: 5
// Media por sesión: 49.0 min
El tercer método, mejorDia, es el máximo de arrays guardando la posición; inténtalo tú. Cada parte se prueba por separado (si la media sale mal, sabes en qué método mirar), se reutiliza (mediaSesion aprovecha contarDiasActivos) y el main se lee como el enunciado.
Una receta para cualquier ejercicio
- Entiende el enunciado: entradas, salida esperada y un ejemplo resuelto a mano.
- Busca los casos especiales: cero, negativos, listas vacías, repetidos.
- Descompón y escribe el pseudocódigo de cada parte.
- Haz la traza con tu ejemplo y con los casos especiales.
- Traduce a Java y ejecuta. Si el resultado no coincide con tu traza, el error está en la traducción; si coincide pero es incorrecto, está en el algoritmo.
Errores frecuentes
- Iniciar mal los acumuladores. Una suma empieza en 0; un producto, en 1; un máximo, en el primer valor (no en 0, que falla con números negativos).
- Olvidar que la variable del bucle tiene que cambiar. Si en un
MIENTRASnunca actualizas la condición (numero ← numero / 10), el bucle no termina. - Probar solo con el ejemplo del enunciado. Haz trazas con casos límite: 0, 1, negativos, valores iguales.
- Diagramas con caminos sin cerrar. Cada rombo tiene dos salidas y las dos deben llegar a algún sitio.
Resumen
| Concepto | Qué es |
|---|---|
| Algoritmo | Pasos precisos, ordenados y finitos que resuelven un problema |
| Secuencia, decisión, repetición | Las tres estructuras con las que se construye cualquier algoritmo |
| Pseudocódigo | El algoritmo en lenguaje natural estructurado, sin sintaxis de ningún lenguaje |
| Diagrama de flujo | El algoritmo dibujado: óvalos, paralelogramos, rectángulos, rombos y flechas |
| Traza | Ejecutar el algoritmo a mano anotando las variables en una tabla |
| Acumulador | Variable que va sumando (empieza en 0) o multiplicando (empieza en 1) |
% 10 y / 10 | Sacar y quitar la última cifra de un número |
| Diseño descendente | Partir un problema grande en subproblemas pequeños |
Ya sabes pensar un algoritmo. Para escribirlo en Java necesitas guardar datos: empieza por variables y tipos.
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.