CLASE_5 Arreglos Unidimensionales y Multidimensionales en C++
A continuación, te presento un tutorial sobre bucles anidados y vectores unidimensionales en C++
Bucles Anidados y Vectores Unidimensionales en C++: Buscando Duplicados
¡Hola! En este tutorial, vamos a explorar dos conceptos fundamentales en la programación que trabajan muy bien juntos: los bucles anidados y los vectores unidimensionales. Para ello, analizaremos un código C++ que busca números duplicados dentro de un conjunto de datos. Este ejemplo práctico te ayudará a entender cómo estas herramientas se combinan para resolver problemas comunes.
1. Entendiendo el Vector Unidimensional
Antes de sumergirnos en los bucles, recordemos qué es un vector unidimensional.
Imagina un vector como una fila de casilleros, cada uno con un número de identificación único (su índice), empezando desde 0. Dentro de cada casillero, puedes guardar un valor.
En nuestro código:
vector<int> cedula = {2, 1, 7, 2, 1, 1, 9, 5};
vector<int>
: Indica que estamos creando un vector que guardará números enteros (int
). La librería<vector>
nos permite usar este tipo de dato dinámico, que es más flexible que los arreglos tradicionales.cedula
: Es el nombre de nuestro vector.= {2, 1, 7, 2, 1, 1, 9, 5};
: Son los valores iniciales que se guardan en los casilleros del vector.
Así se vería nuestro vector cedula
en memoria:
| Índice | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | :----- | :- | :- | :- | :- | :- | :- | :- | :- | | Valor | 2 | 1 | 7 | 2 | 1 | 1 | 9 | 5 |
Podemos acceder a cualquier valor usando su índice, por ejemplo, cedula[0]
es 2, cedula[1]
es 1, y así sucesivamente.
2. Bucles Anidados: Bucles Dentro de Otros Bucles
Un bucle anidado es simplemente un bucle dentro de otro bucle. Piensa en un reloj: la manecilla de los minutos (bucle interno) da 60 vueltas completas por cada vuelta que da la manecilla de las horas (bucle externo).
En programación, los bucles anidados son muy útiles para recorrer estructuras de datos bidimensionales (como matrices) o, como en nuestro caso, para comparar cada elemento de un vector con todos los demás elementos del mismo vector.
En nuestro código, tenemos dos bucles for
:
for (size_t i = 0; i < cedula.size(); ++i) { // Bucle EXTERNO
for (size_t j = 0; j < cedula.size(); ++j) { // Bucle INTERNO
// ... código de comparación ...
}
}
-
Bucle Externo (
for (size_t i = 0; i < cedula.size(); ++i)
):- La variable
i
(índice externo) comenzará en 0 y aumentará de uno en uno hasta quei
sea menor que el tamaño del vector (cedula.size()
que es 8). - En cada iteración de este bucle,
i
seleccionará un elemento "base" del vector.
- La variable
-
Bucle Interno (
for (size_t j = 0; j < cedula.size(); ++j)
):- La variable
j
(índice interno) también comenzará en 0 y aumentará de uno en uno hasta quej
sea menor que el tamaño del vector. - ¡Importante! Por cada valor de
i
en el bucle externo, el bucle interno (j
) se ejecutará completamente desde 0 hasta el final. Esto significa que cada elemento seleccionado pori
será comparado con todos los elementos seleccionados porj
.
- La variable
3. El Algoritmo de Búsqueda de Duplicados (Fuerza Bruta)
El propósito de nuestro código es encontrar si existe al menos un número duplicado en el vector cedula
. Este enfoque es un ejemplo clásico de un algoritmo de fuerza bruta para encontrar duplicados, ya que compara cada elemento con cada uno de los demás.
Vamos a analizar la lógica dentro de los bucles:
if (i != j && cedula[i] == cedula[j]) {
cout << "Se encontro un duplicado: " << cedula[i] << " (en los indices " << i << " y " << j << ")" << endl;
encontrado = true;
break; // Rompe el bucle interno
}
if (i != j && cedula[i] == cedula[j])
: Esta es la condición clave para detectar un duplicado.i != j
: Asegura que no estemos comparando un elemento consigo mismo. Un elemento siempre es igual a sí mismo, pero eso no cuenta como un "duplicado" en el sentido de que haya otra instancia del mismo valor.cedula[i] == cedula[j]
: Verifica si el valor en la posicióni
es igual al valor en la posiciónj
.
- Si la condición es verdadera (se encuentra un duplicado diferente de sí mismo):
- Se imprime un mensaje indicando el número duplicado y sus índices.
encontrado = true;
: Se establece una bandera booleana (bool
) entrue
para recordar que ya encontramos un duplicado.break;
: Esta sentencia es crucial. ¡Rompe el bucle interno (j
)! Una vez que encontramos el primer duplicado, no necesitamos seguir comparando elcedula[i]
actual con el resto de los elementos.
Después del bucle interno, hay otra condición para romper el bucle externo:
if (encontrado) {
break; // Rompe el bucle externo
}
- Si
encontrado
estrue
(porque se encontró un duplicado en alguna de las iteraciones internas), entonces esta línea ejecutabreak;
para romper el bucle externo (i
). ¿Por qué? Porque el objetivo del programa es solo saber si existe al menos un duplicado. Una vez que lo encontramos, podemos detener la búsqueda por completo.
Finalmente, si al terminar todos los bucles (o al romperlos) la variable encontrado
sigue siendo false
, significa que no se encontró ningún duplicado:
if (!encontrado) { // '!' significa "NO", así que '!encontrado' es "si encontrado es falso"
cout << "No se encontraron numeros duplicados en el array." << endl;
}
4. ¿Cómo se Ejecuta el Código? (Traza Simplificada)
Consideremos cedula = {2, 1, 7, 2, 1, 1, 9, 5}
.
-
i = 0
(valorcedula[0] = 2
)j = 0
:i == j
, se salta.j = 1
:cedula[0]
(2)!=
cedula[1]
(1).j = 2
:cedula[0]
(2)!=
cedula[2]
(7).j = 3
:i != j
estrue
,cedula[0]
(2)==
cedula[3]
(2). ¡Duplicado encontrado!- Se imprime:
Se encontro un duplicado: 2 (en los indices 0 y 3)
encontrado = true
.break;
(sale del buclej
).
- Se imprime:
- El bucle externo verifica
if (encontrado)
. Como estrue
,break;
(sale del buclei
).
-
El programa termina la ejecución de los bucles y pasa a la condición final.
-
if (!encontrado)
:!true
esfalse
, así que no se imprime el mensaje "No se encontraron duplicados".
Salida del programa:
Se encontro un duplicado: 2 (en los indices 0 y 3)
5. Compilación y Ejecución
Para probar este código:
- Guarda el código: Copia el código completo y guárdalo en un archivo llamado, por ejemplo,
buscar_duplicados.cpp
. - Abre una terminal/línea de comandos: Navega hasta el directorio donde guardaste el archivo.
- Compila: Usa un compilador de C++ (como g++):
Esto creará un archivo ejecutable llamadoBashg++ buscar_duplicados.cpp -o buscar_duplicados
buscar_duplicados
(obuscar_duplicados.exe
en Windows). - Ejecuta:
Bash
./buscar_duplicados
Este tutorial te ha proporcionado una visión clara de cómo los bucles anidados se utilizan para realizar comparaciones exhaustivas en un vector unidimensional, permitiendo la detección de duplicados. Es un patrón común que encontrarás en muchos problemas de programación.
código completo:
¡Excelente! Con el código que proporcionaste, vamos a crear un tutorial que te ayudará a comprender los bucles anidados y los arreglos bidimensionales de una manera muy práctica: generando tablas de multiplicar.
Bucles Anidados y Arreglos Bidimensionales en C++: Generando Tablas de Multiplicar
¡Hola! Hoy exploraremos cómo los bucles anidados y los arreglos bidimensionales se combinan para manejar y organizar datos de forma estructurada. Utilizaremos un ejemplo muy claro: la creación y visualización de tablas de multiplicar completas.
1. Entendiendo el Arreglo Bidimensional (Matriz)
Mientras que un vector unidimensional es como una fila de casilleros, un arreglo bidimensional (o matriz) es como una cuadrícula o una hoja de cálculo, con filas y columnas. Cada "celda" de la cuadrícula tiene dos índices para identificarla: uno para la fila y otro para la columna.
En nuestro código:
const int NUM_TABLAS = 9; // Definimos el número de tablas (filas)
const int MULTIPLICADORES = 10; // Definimos el número de multiplicadores (columnas)
int tablasDeMultiplicar[NUM_TABLAS][MULTIPLICADORES];
int tablasDeMultiplicar[NUM_TABLAS][MULTIPLICADORES];
: Declara un arreglo bidimensional llamadotablasDeMultiplicar
.NUM_TABLAS
(9): Representa el número de filas. En nuestro caso, serán las tablas del 1 al 9.MULTIPLICADORES
(10): Representa el número de columnas. Serán los resultados de multiplicar hasta 10 (ej. ×1, ×2, ... ×10).
Piensa en esta matriz así:
Para acceder a un elemento, usarías tablasDeMultiplicar[fila][columna]
. Por ejemplo, tablasDeMultiplicar[0][4]
almacenaría el resultado de (porque la fila 0 es la tabla del 1 y la columna 4 es el multiplicador 5).
2. Bucles Anidados: Llenando la Matriz
Para llenar cada "celda" de nuestra matriz tablasDeMultiplicar
, necesitamos recorrer tanto las filas como las columnas. Aquí es donde los bucles anidados son indispensables.
for (int i = 0; i < NUM_TABLAS; ++i) { // Bucle EXTERNO: Recorre las FILAS (tablas)
for (int j = 0; j < MULTIPLICADORES; ++j) { // Bucle INTERNO: Recorre las COLUMNAS (multiplicadores)
// La fila (i) representa la tabla actual (ej. 0 para tabla del 1, 1 para tabla del 2, etc.)
// La columna (j) representa el multiplicador actual (ej. 0 para x1, 1 para x2, etc.)
tablasDeMultiplicar[i][j] = (i + 1) * (j + 1);
}
}
-
Bucle Externo (
for (int i = 0; i < NUM_TABLAS; ++i)
):- Controla las filas de nuestra matriz. La variable
i
irá de 0 a 8 (para 9 tablas). i + 1
se usa para obtener el número de tabla real (ej.0 + 1 = 1
para la tabla del 1,1 + 1 = 2
para la tabla del 2, etc.).
- Controla las filas de nuestra matriz. La variable
-
Bucle Interno (
for (int j = 0; j < MULTIPLICADORES; ++j)
):- Controla las columnas dentro de cada fila. La variable
j
irá de 0 a 9 (para 10 multiplicadores). - Por cada iteración del bucle externo (
i
), el bucle interno (j
) se ejecutará completamente de 0 a 9. j + 1
se usa para obtener el multiplicador real (ej.0 + 1 = 1
para ×1,1 + 1 = 2
para ×2, etc.).
- Controla las columnas dentro de cada fila. La variable
-
tablasDeMultiplicar[i][j] = (i + 1) * (j + 1);
:- Esta línea crucial calcula el resultado de la multiplicación para la celda actual y lo almacena.
- Por ejemplo, cuando
i=0
(Tabla del 1) yj=4
(Multiplicador 5), se almacenará(0+1) * (4+1) = 1 * 5 = 5
entablasDeMultiplicar[0][4]
.
3. Bucles Anidados: Mostrando la Matriz
Una vez que la matriz está llena, necesitamos otra serie de bucles anidados para imprimir su contenido de una manera legible.
for (int tabla = 0; tabla < NUM_TABLAS; ++tabla) { // Bucle EXTERNO: Recorre las "filas" (tablas)
cout << "Tabla del " << (tabla + 1) << endl; // Imprime el encabezado de la tabla (ej: Tabla del 1)
for (int x = 0; x < MULTIPLICADORES; ++x) { // Bucle INTERNO: Recorre las "columnas" (operaciones)
// Accedemos al resultado almacenado y lo imprimimos.
cout << "[ " << (tabla + 1) << " * " << (x + 1) << " = " << tablasDeMultiplicar[tabla][x] << " ] ";
}
cout << "\n----------------------------------------\n"; // Separador entre tablas para mejor legibilidad
}
- Esta sección es muy similar a la de llenado, pero en lugar de asignar valores, los estamos leyendo y mostrando en pantalla.
- Las variables
tabla
yx
se utilizan aquí en lugar dei
yj
para mayor claridad, pero su función es la misma:tabla
itera sobre las filas yx
sobre las columnas. cout << "[ " << (tabla + 1) << " * " << (x + 1) << " = " << tablasDeMultiplicar[tabla][x] << " ] ";
: Imprime cada operación y su resultado de manera formateada, accediendo al valor entablasDeMultiplicar[tabla][x]
.
4. Código Completo y Ejecución
Aquí está el código completo para que puedas copiarlo, compilarlo y ejecutarlo:
#include <iostream> // Para usar cout y endl
using namespace std; // Para no tener que usar std:: antes de cout, etc.
int main() {
// Definimos el tamaño de nuestra matriz usando constantes para mayor claridad
const int NUM_TABLAS = 9; // Representa las filas (tablas del 1 al 9)
const int MULTIPLICADORES = 10; // Representa las columnas (multiplicadores del 1 al 10)
// Declaramos nuestro arreglo bidimensional (matriz)
int tablasDeMultiplicar[NUM_TABLAS][MULTIPLICADORES];
// Bucle para LLENAR la matriz con los resultados de las tablas de multiplicar
for (int i = 0; i < NUM_TABLAS; ++i) { // Recorre las filas (tablas)
for (int j = 0; j < MULTIPLICADORES; ++j) { // Recorre las columnas (multiplicadores)
// Calculamos el valor y lo asignamos a la celda correspondiente
// (i + 1) para obtener el número de tabla real (del 1 al 9)
// (j + 1) para obtener el multiplicador real (del 1 al 10)
tablasDeMultiplicar[i][j] = (i + 1) * (j + 1);
}
}
// Bucle para MOSTRAR el contenido de la matriz (las tablas de multiplicar)
for (int tabla = 0; tabla < NUM_TABLAS; ++tabla) { // Recorre las filas para imprimir cada tabla
// Imprime el encabezado para saber de qué tabla se trata
cout << "Tabla del " << (tabla + 1) << endl;
for (int x = 0; x < MULTIPLICADORES; ++x) { // Recorre las columnas para imprimir cada operación
// Accedemos al resultado almacenado en la matriz y lo mostramos formateado
cout << "[ " << (tabla + 1) << " * " << (x + 1) << " = " << tablasDeMultiplicar[tabla][x] << " ] ";
}
cout << "\n----------------------------------------\n"; // Un separador para diferenciar las tablas
}
return 0; // Indica que el programa finalizó correctamente
}
Pasos para Compilar y Ejecutar:
- Guarda: Copia el código en un archivo de texto y guárdalo como
tablas_multiplicar.cpp
. - Compila: Abre tu terminal o línea de comandos y navega hasta donde guardaste el archivo. Usa un compilador de C++ (como
g++
):Bashg++ tablas_multiplicar.cpp -o tablas_multiplicar
- Ejecuta:
Bash
./tablas_multiplicar
Verás las tablas de multiplicar impresas en tu consola.
Este tutorial te ha mostrado cómo los bucles anidados son la herramienta perfecta para trabajar con arreglos bidimensionales, permitiéndote procesar y organizar datos de forma tabular. Esta combinación es fundamental para tareas como la manipulación de imágenes, juegos (tableros), o cualquier dato que pueda representarse en filas y columnas.
Código completo
Arreglos Multidimensionales (Tres Dimensiones) en C++: Un Almacén Virtual
¡Hola! Hasta ahora hemos trabajado con arreglos unidimensionales (listas) y bidimensionales (tablas o matrices). Hoy daremos un paso más allá para explorar los arreglos multidimensionales de tres dimensiones. Piensa en ellos como cubos o pilas de tablas. Usaremos un ejemplo práctico: la simulación de un almacén con niveles, pasillos y estantes para entender cómo se organizan los datos en un espacio tridimensional.
1. ¿Qué es un Arreglo Tridimensional?
Un arreglo bidimensional tiene filas y columnas (x, y). Un arreglo tridimensional añade una tercera dimensión, que podemos llamar "profundidad" o "altura" (x, y, z). Es como tener múltiples matrices apiladas una encima de la otra.
En C++, puedes declarar un arreglo tridimensional especificando tres tamaños:
tipo nombre[tamaño1][tamaño2][tamaño3];
En nuestro código, utilizamos std::vector
de forma anidada para crear un arreglo tridimensional, que es una práctica más moderna y flexible que los arreglos C-style fijos.
const int NIVELES = 3;
const int PASILLOS = 5;
const int ESTANTES_POR_PASILLO = 10;
// Declaración e inicialización de un arreglo tridimensional usando vectores anidados
std::vector<std::vector<std::vector<std::string>>> almacen(
NIVELES,
std::vector<std::vector<std::string>>(
PASILLOS,
std::vector<std::string>(ESTANTES_POR_PASILLO, ESTANTE_VACIO) // Inicializa con "VACIO"
)
);
Aquí, almacen
representa nuestro espacio tridimensional:
NIVELES
(3): La primera dimensión. Piensa en la altura del almacén, como si fueran 3 pisos.PASILLOS
(5): La segunda dimensión. Dentro de cada nivel, hay 5 pasillos.ESTANTES_POR_PASILLO
(10): La tercera dimensión. Dentro de cada pasillo, hay 10 estantes.
Cada celda de este arreglo (almacen[nivel][pasillo][estante]
) puede almacenar una std::string
, que representa el nombre de un producto (o "VACIO" si está desocupado).
Para acceder a un elemento específico en este "almacén", necesitas tres índices: almacen[nivel][pasillo][estante]
.
2. Inicialización y Asignación de Productos
El código inicializa todos los estantes como "VACIO"
para simular un almacén desocupado. Luego, asigna algunos productos en ubicaciones específicas:
const std::string ESTANTE_VACIO = "VACIO"; // Una constante para el estado vacío
// ... (declaración del almacén) ...
std::cout << "\nAsignando productos a estantes..." << std::endl;
almacen[0][0][0] = "Producto_A_123"; // Nivel 0, Pasillo 0, Estante 0
almacen[0][0][1] = "Producto_B_456"; // Nivel 0, Pasillo 0, Estante 1
almacen[1][2][5] = "Producto_C_789"; // Nivel 1, Pasillo 2, Estante 5
almacen[2][4][9] = "Producto_D_012"; // Nivel 2, Pasillo 4, Estante 9 (el ultimo estante)
almacen[0][3][2] = "Producto_E_345"; // Nivel 0, Pasillo 3, Estante 2
Aquí vemos cómo se usa la notación de tres corchetes [ ] [ ] [ ]
para especificar la ubicación exacta de un producto dentro del almacén. Los índices, como siempre en C++, comienzan desde 0.
3. Acceso y Verificación de Estantes Específicos
Para demostrar cómo acceder a un estante en particular, el código utiliza una función lambda (una función anónima) mostrarEstadoEstante
para verificar el contenido de una ubicación dada:
auto mostrarEstadoEstante = [&](int nivel, int pasillo, int estante) {
if (nivel >= 0 && nivel < NIVELES && // Validar nivel
pasillo >= 0 && pasillo < PASILLOS && // Validar pasillo
estante >= 0 && estante < ESTANTES_POR_PASILLO) { // Validar estante
std::cout << "Nivel " << nivel << ", Pasillo " << pasillo
<< ", Estante " << estante << ": " << almacen[nivel][pasillo][estante] << std::endl;
} else {
std::cout << "Coordenadas de estante fuera de rango." << std::endl;
}
};
// Verificando el estado de algunos estantes
std::cout << "\n--- Verificacion de Estantes Especificos ---" << std::endl;
mostrarEstadoEstante(0, 0, 0); // Un estante con producto
mostrarEstadoEstante(0, 0, 2); // Un estante vacío
mostrarEstadoEstante(99, 0, 0); // Un ejemplo fuera de rango
Esta función es útil para verificar que el acceso a los arreglos esté dentro de los límites definidos (para evitar errores de "fuera de rango").
4. Recorrido Completo del Almacén con Bucles Anidados (¡Triple Bucle!)
Para recorrer y mostrar el contenido de todo el almacén tridimensional, necesitamos tres bucles anidados. Cada bucle se encarga de una de las dimensiones:
std::cout << "\n--- Inventario Completo del Almacen ---" << std::endl;
int productosAlmacenados = 0;
for (int n = 0; n < NIVELES; ++n) { // Bucle EXTERNO: Recorre los NIVELES
std::cout << "\nNIVEL " << n << ":" << std::endl;
for (int p = 0; p < PASILLOS; ++p) { // Bucle MEDIO: Recorre los PASILLOS dentro de cada nivel
std::cout << " Pasillo " << p << ": ";
for (int e = 0; e < ESTANTES_POR_PASILLO; ++e) { // Bucle INTERNO: Recorre los ESTANTES por pasillo
// Accedemos al contenido del estante actual
if (almacen[n][p][e] != ESTANTE_VACIO) {
std::cout << "[" << almacen[n][p][e] << "] ";
productosAlmacenados++;
} else {
std::cout << "[ " << ESTANTE_VACIO << " ] "; // Formato para estantes vacíos
}
}
std::cout << std::endl; // Salto de línea para el siguiente pasillo
}
}
std::cout << "\nTotal de productos almacenados: " << productosAlmacenados << std::endl;
- El bucle más externo (
for (int n = 0; n < NIVELES; ++n)
) itera sobre los NIVELES. - Por cada nivel, el bucle intermedio (
for (int p = 0; p < PASILLOS; ++p)
) itera sobre los PASILLOS. - Finalmente, por cada pasillo, el bucle más interno (
for (int e = 0; e < ESTANTES_POR_PASILLO; ++e)
) itera sobre los ESTANTES.
Esta combinación de tres bucles asegura que se visite cada ubicación única en el espacio tridimensional del almacén. La condición if (almacen[n][p][e] != ESTANTE_VACIO)
se usa para imprimir de manera diferente los estantes que contienen un producto versus los que están vacíos, y para contar los productos.
5. Modificando Contenido
Así como podemos asignar valores, también podemos modificarlos o "eliminar" productos asignando el valor ESTANTE_VACIO
a una ubicación:
// 5. Eliminar un producto de un estante
std::cout << "\n--- Retirando un Producto ---" << std::endl;
int nivelARetirar = 1;
int pasilloARetirar = 2;
int estanteARetirar = 5;
if (almacen[nivelARetirar][pasilloARetirar][estanteARetirar] != ESTANTE_VACIO) {
std::cout << "Retirando " << almacen[nivelARetirar][pasilloARetirar][estanteARetirar]
<< " de Nivel " << nivelARetirar << ", Pasillo " << pasilloARetirar
<< ", Estante " << estanteARetirar << std::endl;
almacen[nivelARetirar][pasilloARetirar][estanteARetirar] = ESTANTE_VACIO; // Lo marca como vacío
mostrarEstadoEstante(nivelARetirar, pasilloARetirar, estanteARetirar); // Muestra el estado actualizado
} else {
std::cout << "El estante ya esta vacio o no existe el producto." << std::endl;
}
Esto demuestra cómo puedes interactuar con una celda específica del arreglo tridimensional para actualizar su contenido.
6. Código Completo y Ejecución
Aquí tienes el código completo para que puedas compilarlo y ejecutarlo:
#include <iostream> // Para entrada y salida estándar (cout, endl)
#include <string> // Para usar std::string
#include <vector> // Para usar std::vector (más flexible que arrays fijos)
// Usamos el namespace std para no tener que escribir std::cout, std::endl, etc.
using namespace std;
// Definimos una constante para representar un estante vacío
const std::string ESTANTE_VACIO = "VACIO";
int main() {
// Dimensiones del almacén:
// NIVELES: Altura del almacén
// PASILLOS: Número de pasillos en cada nivel
// ESTANTES_POR_PASILLO: Número de estantes en cada pasillo
const int NIVELES = 3;
const int PASILLOS = 5;
const int ESTANTES_POR_PASILLO = 10;
// 1. Declaración e inicialización del array tridimensional
// Usamos std::vector<std::vector<std::vector<std::string>>> para mayor flexibilidad.
// Esto es equivalente a un array string almacenes[NIVELES][PASILLOS][ESTANTES_POR_PASILLO];
std::vector<std::vector<std::vector<std::string>>> almacen(
NIVELES, // El primer vector tiene 'NIVELES' elementos
std::vector<std::vector<std::string>>(
PASILLOS, // Cada elemento del primer vector es un vector con 'PASILLOS' elementos
std::vector<std::string>(ESTANTES_POR_PASILLO, ESTANTE_VACIO) // Cada elemento del segundo vector es un vector con 'ESTANTES_POR_PASILLO' elementos, inicializados a "VACIO"
)
);
std::cout << "--- Simulacion de Asignacion de Recursos en Almacen ---" << std::endl;
// 2. Asignación de algunos productos a estantes específicos
std::cout << "\nAsignando productos a estantes..." << std::endl;
almacen[0][0][0] = "Producto_A_123"; // Nivel 0, Pasillo 0, Estante 0
almacen[0][0][1] = "Producto_B_456"; // Nivel 0, Pasillo 0, Estante 1
almacen[1][2][5] = "Producto_C_789"; // Nivel 1, Pasillo 2, Estante 5
almacen[2][4][9] = "Producto_D_012"; // Nivel 2, Pasillo 4, Estante 9 (el ultimo estante)
almacen[0][3][2] = "Producto_E_345"; // Nivel 0, Pasillo 3, Estante 2
// 3. Función para mostrar el estado actual de un estante
// 'auto' permite que el compilador infiera el tipo de la lambda.
// '&' captura las variables del entorno circundante por referencia (como NIVELES, PASILLOS, etc.)
auto mostrarEstadoEstante = [&](int nivel, int pasillo, int estante) {
// Validación de límites para evitar errores de acceso
if (nivel >= 0 && nivel < NIVELES &&
pasillo >= 0 && pasillo < PASILLOS &&
estante >= 0 && estante < ESTANTES_POR_PASILLO) {
std::cout << "Nivel " << nivel << ", Pasillo " << pasillo
<< ", Estante " << estante << ": " << almacen[nivel][pasillo][estante] << std::endl;
} else {
std::cout << "Coordenadas de estante fuera de rango." << std::endl;
}
};
// Verificando el estado de algunos estantes
std::cout << "\n--- Verificacion de Estantes Especificos ---" << std::endl;
mostrarEstadoEstante(0, 0, 0); // Existe y tiene un producto
mostrarEstadoEstante(1, 2, 5); // Existe y tiene un producto
mostrarEstadoEstante(0, 0, 2); // Existe y está vacío
mostrarEstadoEstante(2, 4, 9); // El último estante con producto
mostrarEstadoEstante(99, 0, 0); // Ejemplo de coordenadas fuera de rango
// 4. Recorrido completo del almacén para ver el inventario
std::cout << "\n--- Inventario Completo del Almacen ---" << std::endl;
int productosAlmacenados = 0;
// Bucle externo para los niveles
for (int n = 0; n < NIVELES; ++n) {
std::cout << "\nNIVEL " << n << ":" << std::endl;
// Bucle medio para los pasillos
for (int p = 0; p < PASILLOS; ++p) {
std::cout << " Pasillo " << p << ": ";
// Bucle interno para los estantes
for (int e = 0; e < ESTANTES_POR_PASILLO; ++e) {
// Verificamos si el estante está vacío o tiene un producto
if (almacen[n][p][e] != ESTANTE_VACIO) {
std::cout << "[" << almacen[n][p][e] << "] "; // Mostrar el producto
productosAlmacenados++; // Contar el producto
} else {
std::cout << "[ " << ESTANTE_VACIO << " ] "; // Mostrar que está vacío
}
}
std::cout << std::endl; // Salto de línea para el siguiente pasillo
}
}
std::cout << "\nTotal de productos almacenados: " << productosAlmacenados << std::endl;
// 5. Eliminar un producto de un estante
std::cout << "\n--- Retirando un Producto ---" << std::endl;
int nivelARetirar = 1;
int pasilloARetirar = 2;
int estanteARetirar = 5;
// Antes de retirar, se puede validar si la ubicación contiene algo
if (almacen[nivelARetirar][pasilloARetirar][estanteARetirar] != ESTANTE_VACIO) {
std::cout << "Retirando " << almacen[nivelARetirar][pasilloARetirar][estanteARetirar]
<< " de Nivel " << nivelARetirar << ", Pasillo " << pasilloARetirar
<< ", Estante " << estanteARetirar << std::endl;
almacen[nivelARetirar][pasilloARetirar][estanteARetirar] = ESTANTE_VACIO; // Marcar como vacío
mostrarEstadoEstante(nivelARetirar, pasilloARetirar, estanteARetirar); // Confirmar cambio
} else {
std::cout << "El estante ya esta vacio o no existe el producto." << std::endl;
}
return 0; // Indica que el programa finalizó correctamente
}
Pasos para Compilar y Ejecutar:
- Guarda: Copia el código en un archivo de texto y guárdalo como
almacen_3d.cpp
. - Compila: Abre tu terminal o línea de comandos y navega hasta donde guardaste el archivo. Usa un compilador de C++ (como
g++
):Bashg++ almacen_3d.cpp -o almacen_3d
- Ejecuta:
Bash
./almacen_3d
La salida mostrará la simulación de las operaciones en el almacén, incluyendo el inventario completo.
Comprender los arreglos tridimensionales te abre las puertas a modelar datos en espacios 3D, útil en gráficos de computadora, simulaciones complejas, y más.
Comentarios
Publicar un comentario