CB100

Notas, resueltos y tps de la materia Algoritmos y Estructuras de Datos
Index Commits Files Refs README
commit 1fe8d71338a88ea1d5e90a19ae4bb34026c2247c
parent a7c319cfb5dacdad1606d54d0009e887683ad0be
Author: Martin J. Klöckner <mjkloeckner@gmail.com>
Date:   Sun, 23 Jun 2024 14:59:22 -0300

Merge pull request #17 from mjkloeckner/distance-in-km

Distance in km
Diffstat:
Mbarrio.cpp | 41++++++++++++++++++++++++++---------------
Mbarrio.h | 2+-
Mmenu.cpp | 201+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
3 files changed, 153 insertions(+), 91 deletions(-)
diff --git a/barrio.cpp b/barrio.cpp
@@ -32,27 +32,29 @@ double Barrio::getDistancia(double x1,double y1,double x2,double y2){ //CONSIGAN
     return std::sqrt(dX*dX + dY*dY);
 }
 
-Parada *Barrio::paradaMasCercana(double coordX, double coordY,List<Parada*>* paradasAux) { //CONSIGNA 2
+// lon -> X; lat -> Y;
+Parada *Barrio::paradaMasCercana(double lon, double lat) { //CONSIGNA 2
     double distancia;
-    double distanciaMinima;
+    double distanciaMin;
+
     Parada *resultado, *aux;
 
     resultado = aux = NULL;
 
-    paradasAux->startCursor();
-    while(paradasAux->forwardCursor()){
-        Parada *aux = paradasAux->getCursorData();
+    this->paradas->startCursor();
+    while(this->paradas->forwardCursor()){
+        aux = this->paradas->getCursorData();
 
         if(resultado == NULL) {
             resultado = aux;
-            distanciaMinima = getDistancia(coordX, coordY, aux->getCoordX(), aux->getCoordY());
+            distanciaMin = getDistancia(lon, lat, aux->getCoordX(), aux->getCoordY());
         }
         else {
-            distancia = getDistancia(coordX,coordY,aux->getCoordX(),aux->getCoordY());
+            distancia = getDistancia(lon, lat, aux->getCoordX(),aux->getCoordY());
 
-            if(distancia < distanciaMinima) {
+            if(distancia < distanciaMin) {
                 resultado = aux;
-                distanciaMinima = distancia;
+                distanciaMin = distancia;
             }
         }
     }
@@ -60,7 +62,11 @@ Parada *Barrio::paradaMasCercana(double coordX, double coordY,List<Parada*>* par
     return resultado;
 }
 
-bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas ) { //CONSIGNA 3
+bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas) { //CONSIGNA 3
+    if(listaDeLineas == NULL) {
+        return false;
+    }
+
     for(size_t i = 0; i < listaDeLineas->size(); ++i) {
         if((*listaDeLineas)[i] == linea) {
             return true;
@@ -71,7 +77,7 @@ bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas ) { //CONS
 }
 
 List<Parada*> *Barrio::listaDeParadasPorLinea(int linea) { //CONSIGNA 3
-    Parada *paradaActual;
+    Parada *parada;
     List<Parada*> *resultado;
     std::vector<int> *listaDeLineas;
 
@@ -79,15 +85,20 @@ List<Parada*> *Barrio::listaDeParadasPorLinea(int linea) { //CONSIGNA 3
 
     this->paradas->startCursor();
     while(this->paradas->forwardCursor()){
-        paradaActual = this->paradas->getCursorData();
-        listaDeLineas = paradaActual->getLineas();
+        parada = this->paradas->getCursorData();
+        listaDeLineas = parada->getLineas();
 
         if(lineaEnParada(linea, listaDeLineas)) {
-            resultado->insert(paradaActual);
+            resultado->insert(parada);
         }
     }
 
-    return resultado->getSize() == 0 ? NULL : resultado;
+    if(resultado->getSize() == 0) {
+        delete resultado;
+        return NULL;
+    }
+
+    return resultado;
 }
 
 unsigned int Barrio::getCantidadDeParadasPorLinea(int linea) { //CONSIGNA 4
diff --git a/barrio.h b/barrio.h
@@ -58,7 +58,7 @@ public:
     /*
      * pos: devuelve la parada mas cercana a una coordenada dada
      */
-    Parada *paradaMasCercana(double coordX, double coordY, List<Parada*>* paradasAux);
+    Parada *paradaMasCercana(double coordX, double coordY);
 
     /*
      * pre: recibe el numero de una Linea
diff --git a/menu.cpp b/menu.cpp
@@ -8,6 +8,7 @@
 #include <vector>
 #include <cmath>
 #include <iomanip>
+#include <cctype>
 
 double getDistancia(double x1, double y1, double x2, double y2);
 
@@ -48,11 +49,11 @@ Parada *Menu::paradaMasCercanaPorCoordenada(double coordX, double coordY) {
         barrio = this->barrios->getCursorData();
 
         if(res == NULL) {
-            res = barrio->paradaMasCercana(coordX, coordY, barrio->getParadas());
+            res = barrio->paradaMasCercana(coordX, coordY);
             distanciaMin = getDistancia(coordX, coordY, res->getCoordX(), res->getCoordY());
         }
         else {
-            parada = barrio->paradaMasCercana(coordX, coordY, barrio->getParadas());
+            parada = barrio->paradaMasCercana(coordX, coordY);
             distancia = getDistancia(coordX, coordY, parada->getCoordX(), parada->getCoordY());
 
             if(distanciaMin > distancia) {
@@ -61,16 +62,8 @@ Parada *Menu::paradaMasCercanaPorCoordenada(double coordX, double coordY) {
             }
         }
     }
-    return res;
-}
 
-void Menu::agregarElementosDeLista(List<Parada*>* listaAux, List<Parada*>* listaResultado) {
-    listaAux->startCursor();
-    while(listaAux->forwardCursor()) {
-        Parada *paradaAux = listaAux->getCursorData();
-
-        listaResultado->insert(paradaAux);
-    }
+    return res;
 }
 
 void Menu::imprimirParadasPorLinea(List<Parada*> *listaDeParadas) {
@@ -95,24 +88,36 @@ void Menu::imprimirParadasPorLinea(List<Parada*> *listaDeParadas) {
         }
 }
 
+void Menu::agregarElementosDeLista(List<Parada*>* lista, List<Parada*>* resultado) {
+    Parada *parada;
+
+    lista->startCursor();
+    while(lista->forwardCursor()) {
+        parada = lista->getCursorData();
+
+        resultado->insert(parada);
+    }
+}
+
+
 List<Parada*> *Menu::paradasPorLinea(int linea) {
-    List<Parada*> *listaAux = new List<Parada*>;
-    List<Parada*> *resultado = new List<Parada*>;
+    List<Parada*> *paradas, *resultado;
+    Barrio *barrio;
+
+    resultado = new List<Parada*>;
 
     this->barrios->startCursor();
     while(this->barrios->forwardCursor()){
-        Barrio *barrioAux = this->barrios->getCursorData();
-
-        listaAux = barrioAux->listaDeParadasPorLinea(linea);
-
-        std::cout << "listaAux->getSize(): " << listaAux->getSize() << "\n";
-        // agregarElementosDeLista(listaAux, resultado);
+        barrio = this->barrios->getCursorData();
+        paradas = barrio->listaDeParadasPorLinea(linea);
+        agregarElementosDeLista(paradas, resultado);
     }
 
     if(resultado->getSize() == 0) {
         delete resultado;
         return NULL;
     }
+
     return resultado;
 }
 
@@ -130,8 +135,6 @@ void Menu::agregarElementoSinRepetir(std::vector<int> *lineas, std::vector<int> 
             lineas->push_back((*vectorLineasAux)[i]);
         }
     }
-
-    return;
 }
 
 void Menu::lineasPorParada(List<Parada*> *paradas) {
@@ -153,7 +156,7 @@ void Menu::imprimirCantidadParadasPorLinea(std::vector<int>* lineas){
     for(size_t i=0; i < lineas->size(); i++) {
         paradas = paradasPorLinea((*lineas)[i]);
         if(paradas == NULL) {
-            std::cout << "no hay paradas de la liena especificada\n";
+            std::cout << "no hay paradas de la liena `" << (*lineas)[i] << " `\n";
             continue;
         }
         std::cout << (*lineas)[i] <<" : " << paradas->getSize() <<std::endl;
@@ -182,6 +185,15 @@ Menu::Menu() {
     this->coordX = this->coordY = 0.0f;
 }
 
+std::string strToLowercase(std::string str) {
+    std::string res;
+    for(size_t i = 0; i < str.size(); ++i) {
+        res += std::tolower(str[i]);
+    }
+
+    return res;
+}
+
 void delSurroundingChar(std::string &str, char c) {
     str.erase(0, 1);
     str[str.size() - 1] = '\0';
@@ -252,7 +264,7 @@ Barrio *Menu::getBarrioPorNombre(std::string nombre) {
 
     while(this->barrios->forwardCursor()) {
         barrio = this->barrios->getCursorData();
-        if(barrio->getNombre() == nombre) {
+        if(strToLowercase(barrio->getNombre()) == strToLowercase(nombre)) {
             res = this->barrios->getCursorData();
             break;
         }
@@ -296,31 +308,31 @@ double getDistancia(double x1, double y1, double x2, double y2) {
 }
 
 void ordenarParadasPorDistanciaACoordenada(List<Parada*> *paradas, double x, double y) {
-    Node<Parada*> *actual;
-    Node<Parada*> *minimo;
-    Node<Parada*> *siguiente;
-    double distanciaActual, distanciaSiguiente;
+    Node<Parada*> *actual, *min, *sig;
+    Parada *tmp;
+
+    double distActual, distSig;
 
     paradas->startCursor();
     while(paradas->forwardCursor()) {
         actual = paradas->getCursor();
-        minimo = actual;
-        siguiente = actual->getNext();
+        min = actual;
+        sig = actual->getNext();
 
-        distanciaActual = getDistancia(actual->getData()->getCoordX(), actual->getData()->getCoordY(), x, y);
+        distActual = getDistancia(actual->getData()->getCoordX(), actual->getData()->getCoordY(), x, y);
 
-        while (siguiente != NULL) {
-            distanciaSiguiente = getDistancia(siguiente->getData()->getCoordX(), siguiente->getData()->getCoordY(), x, y);
-            if (distanciaSiguiente < distanciaActual) {
-                minimo = siguiente;
+        while (sig != NULL) {
+            distSig = getDistancia(sig->getData()->getCoordX(), sig->getData()->getCoordY(), x, y);
+            if (distSig < distActual) {
+                min = sig;
             }
-            siguiente = siguiente->getNext();
+            sig = sig->getNext();
         }
 
-        if (minimo != actual) {
-            Parada *temp = actual->getData();
-            actual->setData(minimo->getData());
-            minimo->setData(temp);
+        if (min != actual) {
+            tmp = actual->getData();
+            actual->setData(min->getData());
+            min->setData(tmp);
         }
     }
 }
@@ -418,11 +430,14 @@ void Menu::cargarDatos() {
 
 void Menu::mostrarMenu() {
     bool terminarPrograma = false;
-    std::string opcion;
     int linea;
     double lat, lon; // lat -> Y; lon -> X;
-    double distanciaEnKm;
-    std::string barrio, barrioNombre, lineaAImprimir, distanciaUnidad;
+    double distancia, distanciaEnKm;
+
+    std::string opcion, barrioNombre, lineaAImprimir, distanciaUnidad;
+    List<Parada*> *paradas, *paradasDeLaLinea;
+    Parada *actual;
+    Barrio *barrio;
 
     while(!terminarPrograma) {
         std::cout << "`\033[1m1\033[22m` Cantidad de paradas por barrio\n";
@@ -478,7 +493,7 @@ void Menu::mostrarMenu() {
                     break;
                 }
 
-                distanciaEnKm = getDistanciaEnKilometros(lon, lat, parada->getCoordY(), parada->getCoordX());
+                distanciaEnKm = getDistanciaEnKilometros(lon, lat, parada->getCoordX(), parada->getCoordY());
 
                 if(distanciaEnKm < 1) {
                     distanciaEnKm *= 1000.0f;
@@ -493,7 +508,7 @@ void Menu::mostrarMenu() {
                         << " " << distanciaUnidad << "\n";
                 break;
             case '3':
-                List<Parada*> *paradas;
+                // TODO: verificar que `linea` sea validas
 
                 do {
                     std::cin.clear();
@@ -554,54 +569,90 @@ void Menu::mostrarMenu() {
                 // imprimirCantidadParadasPorLinea(this->lineas);
                 break;
             case '5':
-                /* 
-                 * [X] 0: obtener del usuario `barrio`, `linea` y `coordenadas`
-                 * [X] 1: iterar sobre los barrios para hallar el `barrio`
-                 * [X] 2: crear una lista de las paradas en el `barrio` que contienen la `linea`
-                 * [X] 3: ordenar la lista de menor a mayor con respecto a la distancia a `coordenadas`
-                */
+                // std::cout << "barrio> ";
+                // std::cin >> barrioNombre;
+                barrioNombre.assign("CONSTITUCION");
 
-                // std::cout << "Indique el Barrio: ";
-                // std::cin.ignore(1);
-                // std::getline(std::cin, barrio, '\n');
-                barrioNombre = "CONSTITUCION";
-
-                // std::cout<<"Indique la Linea: ";
-                // std::cin >> this->linea;
-                this->linea = 12;
+                /*
+                do {
+                    std::cin.clear();
+                    std::string line;
+                    std::getline(std::cin, line);
+                    std::cout << "linea> ";
+                    std::cin >> linea;
+                } while(std::cin.fail());
+        
+                // TODO: verificar que `latitud` y `longitud` sean validas
+                do {
+                    std::cin.clear();
+                    std::string line;
+                    std::getline(std::cin, line);
+                    std::cout << "latitud> ";
+                    std::cin >> lat;
+                } while(std::cin.fail());
 
-                // std::cout<<"Indique la coordenada en X: ";
-                // std::cin >> lon;
-                lon = -58.0f;
+                do {
+                    std::cin.clear();
+                    std::string line;
+                    std::getline(std::cin, line);
+                    std::cout << "longitud> ";
+                    std::cin >> lon;
+                } while(std::cin.fail());
 
-                // std::cout<<"Indique la coordenada en Y: ";
-                // std::cin >> lat;
-                lat = -34.0f;
+                */
+                if((barrio = getBarrioPorNombre(barrioNombre)) == NULL) {
+                    std::cout << "No se encontro el barrio `" << barrioNombre << "`\n";
+                    break;
+                }
 
-                Barrio *barrio;
-                List<Parada*> *paradasDeLaLinea;
+                linea = 12;
+                lat = -54.0;
+                lon = -34.0;
 
-                barrio = getBarrioPorNombre(barrioNombre);
-                paradasDeLaLinea = barrio->listaDeParadasPorLinea(this->linea);
+                paradasDeLaLinea = barrio->listaDeParadasPorLinea(linea);
+                if(paradasDeLaLinea == NULL) {
+                    std::cout << "La linea `" << linea
+                        << "` no tiene paradas en el barrio `" << barrioNombre << "`\n";
+                    break;
+                }
 
-                // ordenar de mayor a menor `paradasDeLaLinea`
+                // ordenar de mayor a menor distancia a `lat, lon` la lista `paradasDeLaLinea`
                 ordenarParadasPorDistanciaACoordenada(paradasDeLaLinea, lon, lat);
 
-                Parada *actual;
+                std::cout << std::endl;
+                std::cout.fill(' ');
+                std::cout << std::left << std::setw(18) << std::left << "Direccion"
+                        << std::right << std::setw(35) << "Distancia en Kilometros"
+                        << std::right << std::setw(30) << "Coordenadas (lat, lon)" << std::endl;
+                std::cout.fill('=');
+                std::cout << std::left << std::setw(83) << std::left << "=" << std::endl;
 
                 paradasDeLaLinea->startCursor();
                 while(paradasDeLaLinea->forwardCursor()) {
                     actual = paradasDeLaLinea->getCursorData();
-                    // distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
-                    distanciaEnKm = getDistanciaEnKilometros(lon, lat, actual->getCoordY(), actual->getCoordX());
+                    distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
+                    distanciaEnKm = getDistanciaEnKilometros(lon, lat, actual->getCoordX(), actual->getCoordY());
+
+                    std::string coord;
+                    coord += actual->getCoordX();
+                    // coord += "(";
+                    // coord += actual->getCoordY();
 
                     std::cout.fill('.');
-                    std::cout << std::left << std::setw(25) << actual->getDireccion()
+                    std::cout << std::left << std::setw(33) << actual->getDireccion()
                                 << std::right << std::setw(20)
                                 << std::fixed << std::setprecision(2)
-                                << distanciaEnKm << "  (" << actual->getCoordX() << ", " << actual->getCoordY()
-                                << ")" << std::endl;
+                                << distanciaEnKm;
+
+                    std::cout.fill('.');
+                    std::cout << std::right << std::setw(10) << std::setprecision(4)
+                                << "(" << actual->getCoordX();
+
+                    std::cout.fill(' ');
+                    std::cout << "," << std::right << std::setw(10) << std::setprecision(4)
+                                << actual->getCoordY() << ")" << std::endl;
                 }
+                std::cout << std::endl;
 
                 delete paradasDeLaLinea;
                 break;