En este post te mostraré la solución a un ejercicio en C++ que tiene que ver con archivos CSV y disponibilidad de camas en hospitales.
Básicamente es leer un archivo CSV, pasarlo a la lista enlazada (estructura de datos) y luego generar estadísticas, eliminar repetidos, eliminar un registro y borrarlo.
Nos vamos a basar ampliamente en dos tutoriales que ya he publicado en mi blog: leer archivos CSV con C++ y listas enlazadas en C++.
La Secretaría Regional de cierto lugar del Ministerio de Salud cuenta con datos almacenados dentro de un archivo CSV que registra las camas UCI ocupadas diariamente a nivel regional.
Este archivo representa los datos mediante la siguiente estructura de 3 campos: fecha;codigo_hospital;numero_de_cama
El valor del campo fecha corresponde a la fecha (en formato aaaammdd
) en que fue generado el registro.
El valor del campo codigo_hospital
corresponde a un identificador único para cada hospital de la región y el valor del campo numero_de_cama
es la identificación de la misma.
Al respecto, una cama es única en un hospital; si el mismo número se repite en dos hospitales distintos se trata, entonces, de dos camas diferentes.
Usted debe implementar un programa en lenguaje C++ que dé cobertura a los siguientes requerimientos:
Proveer de un menú de diálogo para el usuario que le permita acceder a las funciones definidas en los puntos anteriores.
Nota: Al seleccionar cada opción, debe mostrar la lista respectiva
Necesitamos la clase Cama que irá dentro de la clase Nodo. Y la clase Lista que maneja los nodos. También necesitamos ciertos métodos que nos permitan eliminar los nodos ya sea por cama (para los duplicados) o por código de hospital.
Igualmente en el constructor de la clase Cama vamos a necesitar separar la fecha por año, mes y día. Para ello cortamos con substr y luego convertimos a entero con stoi
.
Una vez que he explicado los términos generales veamos el código. En este caso primero tenemos el de la lista:
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
| IMPORTANTE |
Si vas a borrar este encabezado, considera:
Seguirme: https://parzibyte.me/blog/sigueme/
Y compartir mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
Twitter: https://twitter.com/parzibyte
Facebook: https://facebook.com/parzibyte.fanpage
Instagram: https://instagram.com/parzibyte
Hacer una donación vía PayPal: https://paypal.me/LuisCabreraBenito
------------------------------------------------------------------------------------------------
*/#include <iostream>
using namespace std;
class Cama
{
public:
string fecha;
int codigoHospital;
string numeroCama;
int dia, mes, anho;
Cama(string fecha, string codigoHospital, string numeroCama)
{
this->fecha = fecha;
this->codigoHospital = stoi(codigoHospital);
this->numeroCama = numeroCama;
// Extraer la fecha desde el constructor
this->anho = stoi(fecha.substr(0, 4));
this->mes = stoi(fecha.substr(4, 2));
this->dia = stoi(fecha.substr(6, 2));
}
void imprimir()
{
cout << "Fecha: " << this->fecha << ". Codigo hospital: " << this->codigoHospital << ". Numero cama: " << this->numeroCama << endl;
}
bool equivale(Cama *otraCama)
{
if (otraCama == NULL)
{
return false;
}
return this->fecha == otraCama->fecha && this->codigoHospital == otraCama->codigoHospital && this->numeroCama == otraCama->numeroCama;
}
};
class Nodo
{
public:
Cama *cama;
Nodo *siguiente;
Nodo(Cama *cama)
{
this->cama = cama;
this->siguiente = NULL;
}
};
class Lista
{
private:
void agregarRecursivo(Nodo *n, Cama *dato)
{
if (n->siguiente == NULL)
{
n->siguiente = new Nodo(dato);
}
else
{
this->agregarRecursivo(n->siguiente, dato);
}
}
void imprimirRecursivo(Nodo *n)
{
if (n != NULL)
{
n->cama->imprimir();
this->imprimirRecursivo(n->siguiente);
}
}
void eliminarRecursivo(Nodo *n, int codigoHospital)
{
if (n == NULL)
{
return;
}
if (n->cama->codigoHospital == codigoHospital && n == this->cabeza)
{
Nodo *temporal = this->cabeza;
if (this->cabeza->siguiente != NULL)
{
this->cabeza = this->cabeza->siguiente;
delete temporal;
}
else
{
this->cabeza = NULL;
}
return;
}
if (n->siguiente != NULL && n->siguiente->cama->codigoHospital == codigoHospital)
{
Nodo *temporal = n->siguiente;
if (n->siguiente != NULL)
{
n->siguiente = n->siguiente->siguiente;
}
delete temporal;
}
else
{
this->eliminarRecursivo(n->siguiente, codigoHospital);
}
}
void eliminarRecursivo(Nodo *n, Cama *camaParaEliminar)
{
if (n == NULL)
{
return;
}
if (n->cama->equivale(camaParaEliminar) && n == this->cabeza)
{
Nodo *temporal = this->cabeza;
if (this->cabeza->siguiente != NULL)
{
this->cabeza = this->cabeza->siguiente;
delete temporal;
}
else
{
this->cabeza = NULL;
}
return;
}
if (n->siguiente != NULL && n->siguiente->cama->equivale(camaParaEliminar))
{
Nodo *temporal = n->siguiente;
if (n->siguiente != NULL)
{
n->siguiente = n->siguiente->siguiente;
}
delete temporal;
}
else
{
this->eliminarRecursivo(n->siguiente, camaParaEliminar);
}
}
bool existeRecursivo(Nodo *n, Cama *camaBuscada)
{
if (n == NULL)
{
return false;
}
if (n->cama->equivale(camaBuscada))
{
return true;
}
return this->existeRecursivo(n->siguiente, camaBuscada);
}
bool existeRecursivo(Nodo *n, int codigoHospital)
{
if (n == NULL)
{
return false;
}
if (n->cama->codigoHospital == codigoHospital)
{
return true;
}
return this->existeRecursivo(n->siguiente, codigoHospital);
}
public:
Nodo *cabeza;
void copiaSinDuplicados(Lista *l)
{
Nodo *temporal = this->cabeza;
while (temporal != NULL)
{
if (!l->existe(temporal->cama))
{
l->agregar(temporal->cama);
}
temporal = temporal->siguiente;
}
}
void eliminar(Cama *cama)
{
this->eliminarRecursivo(this->cabeza, cama);
}
void eliminar(int codigoHospital)
{
this->eliminarRecursivo(this->cabeza, codigoHospital);
}
void agregar(Cama *cama)
{
if (this->cabeza == NULL)
{
this->cabeza = new Nodo(cama);
}
else
{
this->agregarRecursivo(this->cabeza, cama);
}
}
void imprimir()
{
std::cout << "Imprimiendo lista..." << std::endl;
this->imprimirRecursivo(this->cabeza);
}
bool existe(Cama *camaBuscada)
{
return this->existeRecursivo(this->cabeza, camaBuscada);
}
bool existe(int codigoHospital)
{
return this->existeRecursivo(this->cabeza, codigoHospital);
}
};
Luego tenemos el código principal en donde incluimos al archivo anteriormente mostrado, implementamos las funciones y el menú que se solicitó.
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
| IMPORTANTE |
Si vas a borrar este encabezado, considera:
Seguirme: https://parzibyte.me/blog/sigueme/
Y compartir mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
Twitter: https://twitter.com/parzibyte
Facebook: https://facebook.com/parzibyte.fanpage
Instagram: https://instagram.com/parzibyte
Hacer una donación vía PayPal: https://paypal.me/LuisCabreraBenito
------------------------------------------------------------------------------------------------
*/#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
#include "lista.cpp"
using namespace std;
void leeProcesa(string nombreArchivo, Lista *lista)
{
ifstream archivo(nombreArchivo);
string linea;
char delimitador = ';';
// Leemos la primer línea para descartarla, pues es el encabezado
getline(archivo, linea);
// Leemos todas las líneas
while (getline(archivo, linea))
{
stringstream stream(linea); // Convertir la cadena a un stream
string fecha, codigoHospital, numeroCama;
// Extraer todos los valores de esa fila
getline(stream, fecha, delimitador);
getline(stream, codigoHospital, delimitador);
getline(stream, numeroCama, delimitador);
lista->agregar(new Cama(fecha, codigoHospital, numeroCama));
}
archivo.close();
}
void nuevaListaSinDuplicados(Lista *original, Lista *sinDuplicados)
{
original->copiaSinDuplicados(sinDuplicados);
}
void seleccionar(Lista *lista, int codigoHospital, Lista *destino)
{
Nodo *temporal = lista->cabeza;
while (temporal != NULL)
{
if (temporal->cama->codigoHospital == codigoHospital)
{
destino->agregar(temporal->cama);
}
temporal = temporal->siguiente;
}
}
void estadistico(Lista *lista)
{
// Primero vamos a extraer códigos únicos para los hospitales, ya que no sabemos
// si van en orden, si son consecutivos y tampoco sabemos los límites
std::vector<int> codigos;
Nodo *temporal = lista->cabeza;
while (temporal != NULL)
{
int codigoHospital = temporal->cama->codigoHospital;
bool existe = find(codigos.begin(), codigos.end(), codigoHospital) != codigos.end();
if (!existe)
{
codigos.push_back(codigoHospital);
}
temporal = temporal->siguiente;
}
// Ahora recorremos el vector y generamos estadísticas
for (std::size_t i = 0; i < codigos.size(); i++)
{
int codigo = codigos[i];
int conteo = 0;
// Recorremos la lista de nuevo por cada código encontrado
Nodo *temporal = lista->cabeza;
while (temporal != NULL)
{
int codigoHospital = temporal->cama->codigoHospital;
if (codigoHospital == codigo)
{
conteo++;
}
temporal = temporal->siguiente;
}
cout << "Hospital " << codigo << " tiene en total " << conteo << " cama(s) distintas" << endl;
}
}
int contar(Lista *lista, int anho, int mes, int dia)
{
Nodo *temporal = lista->cabeza;
int conteo = 0;
while (temporal != NULL)
{
if (temporal->cama->anho == anho && temporal->cama->mes == mes && temporal->cama->dia == dia)
{
conteo++;
}
temporal = temporal->siguiente;
}
return conteo;
}
void eliminarHospital(Lista *lista, int codigoHospital)
{
while (lista->existe(codigoHospital))
{
lista->eliminar(codigoHospital);
}
}
void menu()
{
string seleccion = "";
Lista *listaConPosiblesRepetidos = new Lista();
Lista *listaSinRepetidos = new Lista();
while (seleccion != "g")
{
cout << "a. Crear lista desde archivo " << endl;
cout << "b. Crear lista sin duplicados" << endl;
cout << "c. Crear lista de un hospital" << endl;
cout << "d. Mostrar estadisticas de numero de camas por hospital" << endl;
cout << "e. Cantidad de camas ocupadas por fecha especificada" << endl;
cout << "f. Eliminar registro de camas de un hospital" << endl;
cout << "g. Salir" << endl;
cout << "Seleccione: " << endl;
cin >> seleccion;
if (seleccion == "a")
{
leeProcesa("camas_ocupadas.csv", listaConPosiblesRepetidos);
cout << "Lista leida desde archivo: " << endl;
listaConPosiblesRepetidos->imprimir();
}
if (seleccion == "b")
{
nuevaListaSinDuplicados(listaConPosiblesRepetidos, listaSinRepetidos);
cout << "Lista sin duplicados: " << endl;
listaSinRepetidos->imprimir();
}
if (seleccion == "c")
{
int codigo;
cout << "Ingresa el codigo de hospital: " << endl;
cin >> codigo;
Lista *deHospital = new Lista();
seleccionar(listaSinRepetidos, codigo, deHospital);
cout << "Datos del hospital solicitado: " << endl;
deHospital->imprimir();
}
if (seleccion == "d")
{
cout << "Estadisticas de la lista:" << endl;
estadistico(listaSinRepetidos);
}
if (seleccion == "e")
{
int anho, mes, dia;
cout << "Ingresa el anho: " << endl;
cin >> anho;
cout << "Ingresa el mes: " << endl;
cin >> mes;
cout << "Ingresa el dia: " << endl;
cin >> dia;
int conteo = contar(listaSinRepetidos, anho, mes, dia);
cout << "Camas ocupadas en fecha: " << conteo << endl;
}
if (seleccion == "f")
{
int codigo;
cout << "Ingresa el codigo de hospital para eliminar: " << endl;
cin >> codigo;
eliminarHospital(listaSinRepetidos, codigo);
cout << "Lista despues de haber eliminado el hospital: " << endl;
listaSinRepetidos->imprimir();
}
}
}
int main()
{
menu();
return 0;
}
Por cierto, el archivo CSV de ejemplo es el siguiente:
fecha;codigo_hospital;numero_de_cama
20210101;20;214
20210101;20;214
20210101;15;197
20210101;16;296
20210101;16;108
20210101;17;152
20210101;20;291
20210101;14;249
20200303;14;105
20210101;16;177
20210101;16;292
20210103;19;160
20210101;16;155
20210101;16;107
20210101;16;107
20200101;11;179
20200101;11;260
Finalmente puedes leer más sobre C++ en el blog de Parzibyte.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.