Arreglos y Vectores
Aprende a almacenar colecciones de datos usando arreglos y vectores en C++
¿Qué es un arreglo?
Imagina que tienes 100 estudiantes y quieres guardar la calificación de cada uno. Sin arreglos, necesitarías 100 variables: cal1, cal2, cal3, ..., cal100. ¡Imposible de manejar!
Un arreglo es una colección de variables del mismo tipo, todas agrupadas bajo un mismo nombre. Es como un edificio de departamentos: un solo edificio con muchos departamentos numerados, y cada departamento guarda un valor.
Arreglo "calificaciones":
┌──────┬──────┬──────┬──────┬──────┐
│ 85 │ 92 │ 78 │ 95 │ 88 │
├──────┼──────┼──────┼──────┼──────┤
│ [0] │ [1] │ [2] │ [3] │ [4] │ ← Índices
└──────┴──────┴──────┴──────┴──────┘
Arreglos estáticos (de C)
Declaración
int calificaciones[5]; // Arreglo de 5 enteros (sin inicializar)
int numeros[5] = {10, 20, 30, 40, 50}; // Inicializado con valores
int ceros[100] = {0}; // Todos inicializados a 0
int masNumeros[] = {1, 2, 3}; // El tamaño se deduce (3 elementos)
Acceso por índice
Los índices empiezan en 0 (no en 1):
int arr[5] = {10, 20, 30, 40, 50};
cout << arr[0] << endl; // 10 (primer elemento)
cout << arr[1] << endl; // 20 (segundo elemento)
cout << arr[4] << endl; // 50 (último elemento)
arr[2] = 99; // Cambiar el tercer elemento
cout << arr[2] << endl; // 99
¡Los índices empiezan en 0! Un arreglo de tamaño n tiene índices del 0 al n-1. Acceder a arr[n] o arr[-1] es un error grave (undefined behavior) que puede causar resultados impredecibles o que tu programa se cierre.
Recorrer un arreglo
int arr[5] = {10, 20, 30, 40, 50};
int n = 5;
// Imprimir todos los elementos
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
// Salida: 10 20 30 40 50
Leer un arreglo
int n;
cin >> n;
int arr[100001]; // Declarar con tamaño máximo posible
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
Arreglos globales vs locales
// Global: se inicializa automáticamente a 0, puede ser muy grande
int arrGlobal[1000001];
int main() {
// Local: NO se inicializa (basura), tamaño limitado (~1MB de stack)
int arrLocal[1000001]; // ⚠️ Puede causar stack overflow
return 0;
}
En competencias, declara arreglos grandes como variables globales. Las variables locales viven en el "stack" que tiene un tamaño limitado (~1-8 MB). Las globales viven en un segmento diferente sin ese límite.
Vectores (la versión moderna y flexible)
Un vector es como un arreglo, pero puede cambiar de tamaño. Es la estructura de datos más usada en C++ competitivo.
Incluir la biblioteca
#include <vector>
// O simplemente #include <bits/stdc++.h>
Crear vectores
vector<int> v; // Vector vacío de enteros
vector<int> v(5); // Vector de 5 elementos (todos en 0)
vector<int> v(5, -1); // Vector de 5 elementos, todos valen -1
vector<int> v = {10, 20, 30}; // Vector con valores iniciales
vector<string> nombres; // Vector de strings
vector<double> decimales(100, 0.0); // 100 elementos, todos 0.0
Operaciones básicas
vector<int> v;
// Agregar elementos al final
v.push_back(10); // v = {10}
v.push_back(20); // v = {20}
v.push_back(30); // v = {10, 20, 30}
// Tamaño
cout << v.size() << endl; // 3
// Acceder por índice (igual que arreglos)
cout << v[0] << endl; // 10
cout << v[1] << endl; // 20
v[2] = 99; // Cambiar un elemento
// Último elemento
cout << v.back() << endl; // 99
// Primer elemento
cout << v.front() << endl; // 10
// Eliminar el último elemento
v.pop_back(); // v = {10, 20}
// ¿Está vacío?
cout << v.empty() << endl; // 0 (false, no está vacío)
// Limpiar todo
v.clear(); // v = {} (vacío)
cout << v.empty() << endl; // 1 (true)
Recorrer un vector
vector<int> v = {10, 20, 30, 40, 50};
// Forma 1: con índice
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
// Forma 2: for-each (más elegante)
for (int x : v) {
cout << x << " ";
}
// Forma 3: for-each por referencia (si quieres modificar)
for (int &x : v) {
x *= 2; // Duplica cada elemento
}
Leer un vector
int n;
cin >> n;
vector<int> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
Arreglos vs Vectores
| Característica | Arreglo | Vector |
|---|---|---|
| Tamaño | Fijo al declarar | Puede crecer/reducir |
| Saber el tamaño | Debes recordar n | v.size() |
| Agregar elementos | No se puede | push_back() |
| Inicialización | Manual o parcial | Automática |
| Velocidad | Ligeramente más rápido | Casi igual |
En competencias, la mayoría de los programadores usan vectores por su flexibilidad.
Operaciones comunes en competencias
Sumar todos los elementos
vector<int> v = {3, 1, 4, 1, 5};
int suma = 0;
for (int x : v) {
suma += x;
}
cout << suma << endl; // 14
Encontrar máximo y mínimo
vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
int maximo = *max_element(v.begin(), v.end());
int minimo = *min_element(v.begin(), v.end());
cout << "Max: " << maximo << ", Min: " << minimo << endl;
// Max: 9, Min: 1
Ordenar
vector<int> v = {5, 2, 8, 1, 9, 3};
sort(v.begin(), v.end()); // Orden ascendente: 1 2 3 5 8 9
sort(v.rbegin(), v.rend()); // Orden descendente: 9 8 5 3 2 1
Invertir
vector<int> v = {1, 2, 3, 4, 5};
reverse(v.begin(), v.end());
// v = {5, 4, 3, 2, 1}
Eliminar duplicados
vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
sort(v.begin(), v.end()); // Primero ordenar
v.erase(unique(v.begin(), v.end()), v.end()); // Eliminar duplicados
// v = {1, 2, 3, 4, 5, 6, 9}
Buscar un elemento
vector<int> v = {10, 20, 30, 40, 50};
// Buscar si existe
auto it = find(v.begin(), v.end(), 30);
if (it != v.end()) {
cout << "Encontrado en posición " << (it - v.begin()) << endl;
} else {
cout << "No encontrado" << endl;
}
Vectores 2D (matrices con vectores)
// Crear una matriz de 3x4 llena de ceros
int filas = 3, cols = 4;
vector<vector<int>> matriz(filas, vector<int>(cols, 0));
// Acceder
matriz[0][0] = 1;
matriz[1][2] = 5;
// Recorrer
for (int i = 0; i < filas; i++) {
for (int j = 0; j < cols; j++) {
cout << matriz[i][j] << " ";
}
cout << endl;
}
Arreglo de frecuencias
Un patrón extremadamente común: contar cuántas veces aparece cada valor.
int n;
cin >> n;
vector<int> v(n);
for (int i = 0; i < n; i++) cin >> v[i];
// Si los valores van de 0 a MAX
int freq[100001] = {0};
for (int x : v) {
freq[x]++;
}
// ¿Cuántas veces aparece el 5?
cout << freq[5] << endl;
Ejercicio de práctica
Lee N números. Imprime cuántos son mayores que el promedio.
Entrada:
5
10 20 30 40 50
Salida: 3 (el promedio es 30, y 30 no es "mayor que" 30, pero 40 y 50 sí... ¡espera! Veamos: promedio = 30. Mayores estrictos que 30: 40 y 50. Son 2.)
Ver solución
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> v(n);
double suma = 0;
for (int i = 0; i < n; i++) {
cin >> v[i];
suma += v[i];
}
double promedio = suma / n;
int cuenta = 0;
for (int x : v) {
if (x > promedio) {
cuenta++;
}
}
cout << cuenta << endl;
return 0;
}
Nota: Necesitamos guardar todos los valores en un vector porque primero debemos calcular el promedio (recorremos una vez) y luego contar cuántos lo superan (recorremos de nuevo).
Siguiente paso
Aprende sobre Strings para manipular texto de forma poderosa en C++.
