2.07 · Patrones: Contadores, Acumuladores y Centinelas
🎯 Objetivo de aprendizaje
Al terminar este tema vas a poder:
- Reconocer los 5 patrones algorítmicos más usados en bucles: suma, promedio, mayor/menor, búsqueda, conteo por condición.
- Aplicar cada patrón con while, do-while y for según el contexto.
- Combinar patrones para resolver problemas más complejos (ej: "suma de los pares" = filtro + acumulador).
- Usar el patrón "mayor/menor" con el "algoritmo del centinela" para encontrar extremos en secuencias.
- Resolver problemas de entrevistas junior usando estos patrones (los 5 más comunes).
- Trazar manualmente cualquier combinación de patrones con datos de prueba.
Los patrones son el 80% de los problemas algorítmicos que vas a enfrentar en tu carrera: exámenes, entrevistas, trabajo real. Si dominas estos 5 patrones, puedes resolver el 80% de los problemas típicos de un junior.
🧠 Teoría y conceptos — 2.7.1 — Los 5 patrones algorítmicos fundamentales

Definición
Un patrón algorítmico es una estructura de código reutilizable que resuelve una clase de problemas. Si aprendes a reconocer los patrones, puedes resolver problemas nuevos descomponiéndolos en patrones conocidos.
Los 5 patrones (los más usados)
Cómo reconocer un patrón
Cuando leas un problema, busca pistas en el enunciado:
- "...calcular la suma de..." → Patrón 1
- "...el promedio de..." → Patrón 2 (suma + conteo)
- "...el número más grande de..." → Patrón 3
- "...buscar un elemento que..." → Patrón 4
- "...cuántos números cumplen..." → Patrón 5
Si el problema pide 2 o más cosas, es una combinación de patrones.
los 5 patrones con su "fórmula" en pseudocódigo. Memorízalos.
2.7.2 — Patrón 1: Suma (acumulador)

El patrón
suma = 0; // Inicialización (en 0)
for (/* cada elemento */) {
suma += elemento; // Acumulación
}
// Al final: 'suma' tiene la suma de todos los elementos
Ejemplo: suma de los primeros 100 naturales
int suma = 0;
for (int i = 1; i <= 100; i++) {
suma += i;
}
cout << "Suma: " << suma << endl; // 5050
Diagrama de flujo clásico del patrón suma
┌─────────────┐
│ INICIO │ ⬭
└──────┬──────┘
│
▼
╱─────────────╲
║ suma = 0 ║ ▭ (inicialización)
╚═══════════════╝
│
▼
◆─────────────◆ ◇
╱ ╲
¿Hay más No ──────►
elementos? │
──────── │
│ │ │
Sí │ │ No │
▼ │ ▼
╔═════════════╗ ║ suma = ║ ▭ (salida)
║ LEER ║ ║ suma + x ║
║ elemento x ║ ╚══════╤════╝
╚══════╤══════╝ │
│ │
▼ │
╔═════════════╗ │
║ suma = ║ │
║ suma + x ║ │
╚══════╤══════╝ │
│ │
└────────┬────────┘
│
└──► (vuelve al rombo de "¿Hay más?")
Variantes del patrón
Suma con filtro: sumar SOLO los que cumplen condición.
int sumaPares = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) { // Solo pares
sumaPares += i;
}
}
cout << "Suma de pares: " << sumaPares << endl; // 2550
Suma hasta centinela:
int suma = 0, numero;
cout << "Números (0 para terminar):" << endl;
cin >> numero; // Priming read
while (numero != 0) {
suma += numero;
cin >> numero;
}
cout << "Suma: " << suma << endl;
2.7.3 — Patrón 2: Promedio (suma + conteo)

El patrón
suma = 0;
contador = 0;
for (/* cada elemento */) {
suma += elemento;
contador++;
}
if (contador > 0) {
}
// Al final: 'promedio' tiene el promedio, 'contador' tiene la cantidad
⚠️ El error #1: división entera
// ❌ MAL: división entera, resultado es 2 (no 2.5)
int suma = 5, contador = 2;
int promedio = suma / contador;
// ✅ BIEN: división decimal
double promedio = (double)suma / contador; // 2.5
Regla: SIEMPRE conviertes a double (o float) al menos UNO de los operandos antes de dividir.
Validación del divisor
if (contador > 0) {
} else {
cout << "No hay datos para promediar" << endl;
}
Si `contador == 0`, divides entre cero = crash.
Ejemplo: promedio de N calificaciones
int n;
double suma = 0, promedio;
int contador = 0;
cout << "¿Cuántas calificaciones? ";
cin >> n;
for (int i = 1; i <= n; i++) {
double cal;
cout << "Calificación " << i << ": ";
cin >> cal;
if (cal >= 0 && cal <= 10) { // Validar
suma += cal;
contador++;
}
}
if (contador > 0) {
cout << "Promedio: " << promedio << endl;
} else {
cout << "No hay calificaciones válidas" << endl;
}
2.7.4 — Patrón 3: Mayor/menor (algoritmo del centinela)

El patrón
// Inicialización: el primer elemento es "candidato" a mayor
mayor = secuencia[0]; // O el primero que leas
for (/* cada elemento */) {
if (elemento > mayor) {
mayor = elemento; // Actualizar el candidato
}
}
// Al final: 'mayor' es el elemento más grande
La clave: inicializar con el PRIMER elemento
// ❌ MAL: inicializar en 0 falla si todos los números son negativos
int mayor = 0;
int nums[] = {-5, -3, -10, -1};
// Resultado: 0 (incorrecto, debería ser -1)
// ✅ BIEN: inicializar con el primer elemento
int mayor = nums[0]; // -5
// Iteración: -5 > -5? No. -3 > -5? Sí → mayor = -3
// -10 > -3? No. -1 > -3? Sí → mayor = -1 ✓
Variante: encontrar menor
menor = secuencia[0];
for (/* ... */) {
if (elemento < menor) {
menor = elemento;
}
}
Variante: encontrar la posición del mayor
int mayorPos = 0;
for (int i = 1; i < n; i++) {
if (arreglo[i] > arreglo[mayorPos]) {
mayorPos = i;
}
}
cout << "Mayor: " << arreglo[mayorPos] << " en posición " << mayorPos << endl;
Ejemplo: mayor de N números ingresados por el usuario
int n, numero, mayor;
cout << "¿Cuántos números? ";
cin >> n;
cout << "Número 1: ";
cin >> numero;
mayor = numero; // Inicializar con el primero
for (int i = 2; i <= n; i++) {
cout << "Número " << i << ": ";
cin >> numero;
if (numero > mayor) {
mayor = numero;
}
}
cout << "El mayor es: " << mayor << endl;
Diagrama de flujo del patrón mayor
┌─────────────┐
│ INICIO │ ⬭
└──────┬──────┘
│
▼
╱───────────────╲
║ LEER primero ║ ▱
║ mayor = x ║
╚════════╤════════╝
│
▼
◆─────────────◆ ◇
╱ ╲
¿Hay más No ──────►
elementos? │ ╔══════════╗
──────── │ ║ ESCRIBIR ║ ▱
│ │ │ ║ mayor ║
Sí │ │ No │ ╚══════════╝
▼ │ ▲
╔═══════════╗ │
║ LEER x ║ ▱ │
╚═════╤═════╝ │
│ │
▼ │
╔═══════════════╗ │
║ ¿x > mayor? ║ ◇ │
╚══╤═════════╤══╝ │
│ Sí │ No │
▼ │ │
╔══════════╗ │ │
║ mayor = x ║ ▭ │
╚══╤═══════╝ │ │
└────┬────┘ │
│ │
└────► (vuelve a "¿Hay más?")
el patrón mayor/menor. Memorízalo: inicializa con el primer elemento, no con 0.
2.7.5 — Patrón 4: Búsqueda (lineal con bandera)

El patrón
posicion = -1; // Bandera: -1 significa "no encontrado"
for (/* cada elemento */) {
if (elemento == objetivo) {
posicion = i; // ¡Encontrado!
break; // Salir del bucle
}
}
// Verificar la bandera
if (posicion != -1) {
cout << "Encontrado en posición " << posicion << endl;
} else {
cout << "No encontrado" << endl;
}
La clave: la bandera (flag)
La variable posicion (o encontrado, o bool encontrado) funciona como centinela lógica: si vale -1 (o false), no se encontró; si vale otra cosa (o true), se encontró.
Búsqueda con while y centinela
int numero, objetivo;
bool encontrado = false;
cout << "Número a buscar: "; cin >> objetivo;
cout << "Ingresa números (0 para terminar):" << endl;
cin >> numero; // Priming read
while (numero != 0 && !encontrado) {
if (numero == objetivo) {
encontrado = true;
} else {
cin >> numero;
}
}
cout << (encontrado ? "Encontrado" : "No encontrado") << endl;
Búsqueda con for y break
int nums[] = {10, 25, 7, 40, 15};
int objetivo = 7;
int posicion = -1;
for (int i = 0; i < 5; i++) {
if (nums[i] == objetivo) {
posicion = i;
break; // Salir al encontrar
}
}
if (posicion != -1) {
cout << "Encontrado en posición " << posicion << endl;
}
2.7.6 — Patrón 5: Conteo por condición (filtro)

El patrón
contador = 0;
for (/* cada elemento */) {
if (/* condición de filtro */) {
contador++; // Solo contar los que cumplen
}
}
Ejemplo: contar positivos, negativos y ceros
int nums[] = {5, -3, 0, 8, -1, 0, 12, -7};
int positivos = 0, negativos = 0, ceros = 0;
for (int i = 0; i < 8; i++) {
if (nums[i] > 0) positivos++;
else if (nums[i] < 0) negativos++;
else ceros++;
}
cout << "Positivos: " << positivos << endl; // 3
cout << "Negativos: " << negativos << endl; // 3
cout << "Ceros: " << ceros << endl; // 2
Variante: con entrada del usuario y centinela
int positivos = 0, negativos = 0, numero;
cout << "Números (0 para terminar):" << endl;
cin >> numero;
while (numero != 0) {
if (numero > 0) positivos++;
else if (numero < 0) negativos++;
cin >> numero;
}
cout << "Positivos: " << positivos << endl;
cout << "Negativos: " << negativos << endl;
2.7.7 — Combinación de patrones
Por qué combinar
Los problemas reales casi nunca son UN solo patrón. Suelen ser combinaciones:
Ejemplo: "Suma de los pares y promedio de los impares"
int n, numero;
int sumaPares = 0, sumaImpares = 0, contadorImpares = 0;
cout << "¿Cuántos números? "; cin >> n;
for (int i = 1; i <= n; i++) {
cout << "Número " << i << ": ";
cin >> numero;
if (numero % 2 == 0) {
sumaPares += numero; // Patrón suma + filtro
} else {
sumaImpares += numero; // Patrón suma
contadorImpares++; // Patrón conteo
}
}
cout << "Suma de pares: " << sumaPares << endl;
if (contadorImpares > 0) {
double promedioImpares = (double)sumaImpares / contadorImpares;
cout << "Promedio de impares: " << promedioImpares << endl;
} else {
cout << "No hay impares" << endl;
}
3 combinaciones de patrones con problemas de tu vida real. Descompón cada uno en los patrones básicos.
2.7.8 — Patrones en entrevistas: los 10 problemas más comunes
Los 10 problemas algorítmicos más frecuentes en entrevistas junior
Basado en análisis de entrevistas técnicas en México y EE.UU. para vacantes junior:
Plantilla para resolver CUALQUIER problema algorítmico
- Lee el problema 3 veces.
- Identifica:
- ¿Qué me piden? (suma, mayor, búsqueda, etc.)
- ¿Qué datos tengo? (entrada)
- ¿Qué quiero obtener? (salida)
- Identifica el PATRÓN o patrones.
- Escribe el pseudocódigo a mano.
- Traza con 2-3 datos de prueba.
- Codifica.
- Ejecuta con los mismos datos y compara.
los 10 problemas algorítmicos más comunes en entrevistas. Practica cada uno en tu cuaderno antes de codearlo.
🤖 IA como copiloto — 🤖 AI Mission 2.7
Prompt 1: "Te voy a pegar un problema algorítmico. NO me des la solución. Solo dime: (1) qué patrón(es) usa, (2) qué variables clave necesito, (3) cuál sería la estructura del bucle. Máximo 150 palabras."
Prompt 2: "Necesito resolver el problema 'suma de los múltiplos de 3 entre 1 y 100'. Dame el código en C++ usando el patrón suma + filtro. Explícame paso a paso. Máximo 200 palabras."
Prompt 3: "Te voy a pegar mi implementación del patrón mayor/menor. NO me corrijas. Solo dime: (1) si inicializo correctamente la variable mayor, (2) si hay un caso borde que no estoy manejando, (3) si el bucle es eficiente. Máximo 150 palabras."
🧪 Laboratorio — 🧪 LAB 2.7 — 7 ejercicios de patrones
🛠️ Herramienta recomendada para los diagramas de flujo de este LAB: Para los ejercicios que pidan un diagrama de flujo, usa [draw.io (diagrams.net)](https://app.diagrams.net/) — herramienta gratis, sin registro, que funciona en el navegador. Tiene plantillas con la simbología ANSI/ISO lista (en `General → Flowchart`). Exporta tus diagramas como PNG e insértalos en tu cuaderno digital o entrégalos junto con el código. Otras opciones libres: - [Mermaid](https://mermaid.live/) — diagramas desde código Markdown. Ideal para Git. - [Excalidraw](https://excalidraw.com/) — estilo "dibujado a mano", muy intuitivo. - Dibujar a mano en tu cuaderno — siempre válido, especialmente para trazar el razonamiento.
Ejercicio 1 — Suma de los primeros N naturales (básico, 10 min)
Enunciado. Pide N al usuario y calcula la suma de los primeros N naturales (1+2+3+...+N) usando for.
Criterio de éxito: con N=100, suma=5050.
Rúbrica (10 pts): bucle correcto (5 pts) + cálculo (3 pts) + verificación (2 pts).
Ejercicio 2 — Promedio con validación (básico, 15 min)
Enunciado. Pide 5 calificaciones al usuario. Calcula el promedio, pero solo de las válidas (entre 0 y 10). Si no hay ninguna válida, muestra "No hay calificaciones".
Rúbrica (10 pts): bucle (3 pts) + validación (4 pts) + promedio (3 pts).
Ejercicio 3 — Mayor y menor (básico, 15 min)
Enunciado. Pide N al usuario, luego N números. Encuentra y muestra el mayor y el menor. No inicialices con 0, usa el primer número como referencia.
Criterio de éxito: con N=5 y nums {3, 7, 2, 9, 5}, mayor=9, menor=2.
Rúbrica (10 pts): mayor (3 pts) + menor (3 pts) + inicialización correcta (4 pts).
Ejercicio 4 — Conteo por condición (intermedio, 20 min)
Enunciado. Pide N al usuario y luego N números. Cuenta cuántos son positivos, negativos, pares, y múltiplos de 5. Muestra los 4 contadores.
Criterio de éxito: con N=10 y nums {-3, 5, 8, 10, -7, 0, 15, 2, 20, -1}, positivos=6, negativos=3, pares=5, múltiplos de 5=4.
Rúbrica (10 pts): 4 contadores × 2 pts + bucle correcto (2 pts).
Ejercicio 5 — Búsqueda con bandera (intermedio, 25 min)
Enunciado. Pide N, luego N números, luego un número a buscar. Di si está y en qué posición. Usa el patrón de búsqueda con bandera. Si NO está, muestra "No encontrado".
Criterio de éxito: con nums {10, 25, 7, 40, 15} y objetivo 7, debe decir "Posición 2".
Rúbrica (10 pts): bucle (3 pts) + bandera (3 pts) + mensaje correcto (4 pts).
Ejercicio 6 — Combinación suma + filtro + mayor (avanzado, 30 min)
Enunciado. Pide N calificaciones. Calcula: suma total, cantidad de aprobados (>= 7), promedio de los aprobados, y la calificación mayor entre los aprobados. Si no hay aprobados, muestra "No hay aprobados".
Rúbrica (10 pts): suma (2 pts) + filtro (2 pts) + promedio (3 pts) + mayor (3 pts).
Ejercicio 7 — FizzBuzz clásico de entrevistas (avanzado, 30 min)
Enunciado. Imprime los números del 1 al 100, pero:
- Si el número es múltiplo de 3, imprime "Fizz".
- Si es múltiplo de 5, imprime "Buzz".
- Si es múltiplo de ambos (3 y 5), imprime "FizzBuzz".
- En otros casos, imprime el número.
Criterio de éxito: la salida sigue el patrón FizzBuzz correctamente.
Rúbrica (10 pts): bucle (2 pts) + condiciones correctas (4 pts) + orden de las condiciones (2 pts) + output (2 pts).
Ejercicio bonus — Números perfectos (opcional, 30 min)
Enunciado. Un número es perfecto si la suma de sus divisores propios (excluyendo al número) es igual al número. Ejemplo: 6 = 1+2+3. Pide N y di si es perfecto, mostrando sus divisores.
Rúbrica bonus (5 pts): algoritmo (3 pts) + output (2 pts).
🎯 Cierre del tema
Lo que aprendiste hoy:
- Los 5 patrones algorítmicos fundamentales: suma, promedio, mayor/menor, búsqueda, conteo.
- Cómo combinar patrones para problemas complejos.
- Los 10 problemas algorítmicos más comunes en entrevistas junior.
- La plantilla para resolver cualquier problema algorítmico.
Lo que sigue: en el Tema 2.8 — Testing: Pruebas de Escritorio y `assert` (6h), vas a aprender a verificar que tu código funciona correctamente sin tener que ejecutarlo mentalmente. Es la base del testing profesional: una habilidad que te separa de un junior "que programa" de un junior "que programa confiablemente".
XP obtenida al completar este tema: 100 base + 30 por LAB (7 ejercicios) + 20 por Quest = 150 XP.
*"Un junior que domina los 5 patrones resuelve el 80% de los problemas. Un senior los combina con otros patrones para el otro 20%."* — De la introducción de este manual.
Fin del Tema 2.7
📝 Quest · Cuestionario — 📝 Quest — Reactivos para autoevaluación
Las siguientes preguntas te sirven para autoevaluarte después de leer el tema. Responde en tu cuaderno o mentalmente, y luego revisa las Respuestas modelo (disponibles en libre acceso, sin iniciar sesión).
Sección A · Opción múltiple
Elige la opción correcta (A, B, C o D). Las respuestas están en la sección Respuestas modelo.
- ¿Qué es un contador?
- Una variable que cuenta ocurrencias
- Un bucle
- Una función
- Un array
- Patrón clásico de contador en C++:
- ++x
- contador++ o contador = contador + 1
- contador += 2
- contador = 0
- ¿Qué es un acumulador?
- Una batería
- Variable que suma valores progresivamente
- Un bucle
- Una constante
- Diferencia entre contador y acumulador:
- Son iguales
- Contador += 1; acumulador += valor variable
- Acumulador no existe
- Contador no existe
- ¿Qué es un centinela (sentinel)?
- Un valor especial que marca fin de datos
- Un error
- Un tipo de variable
- Un bucle
- ¿Cómo se lee una serie de números hasta -1?
- for(;;)
- while (n != -1) { ... }
- if
- switch
- Ejemplo de acumulador en suma:
- i++
- suma = suma + nota
- for
- if
- Para calcular un promedio, ¿qué patrón se usa?
- Solo contador
- Acumulador + contador: promedio = suma / n
- Solo acumulador
- switch
- Una serie de números termina con 0. ¿Qué patrón es?
- Contador
- Centinela (0 marca fin)
- Acumulador
- for infinito
- Patrón max-min en una serie:
- Solo acumulador
- Actualizar max/min al leer cada número
- Centinela
- for
Sección B · Preguntas abiertas
Desarrolla tu respuesta en al menos 3 líneas. Compara con la respuesta modelo después de escribir.
- Diseña un algoritmo que cuente cuántos números positivos, negativos y ceros hay en un arreglo de n elementos.→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
- ¿Cómo calcularías el promedio de una serie de números usando contador y acumulador?→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
- Explica el patrón centinela con un ejemplo de validación de entrada de usuario.→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
🟢 Cuando termines, revisa las Respuestas modelo y compáralas con las tuyas. La mejor forma de aprender es discutir cada respuesta contigo mismo o con un compañero.