From 9bc260a750ad0969ae9c5a410991e01dde25ca73 Mon Sep 17 00:00:00 2001 From: binlab Date: Mon, 1 Dec 2025 23:41:00 +0100 Subject: [PATCH] 302 --- Makefile | 16 ++++-- arbol.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++ arbol.hpp | 9 ++-- cuac.cpp | 7 ++- cuac.hpp | 4 +- diccionariocuacs.cpp | 16 +++++- diccionariocuacs.hpp | 3 ++ fecha.cpp | 6 +++ fecha.hpp | 3 ++ main.cpp | 8 ++- nodo.cpp | 79 +++++++++++++++++++++++++---- nodo.hpp | 5 +- tablahash.cpp | 9 ++-- tablahash.hpp | 10 +--- 14 files changed, 254 insertions(+), 38 deletions(-) create mode 100644 arbol.cpp diff --git a/Makefile b/Makefile index 723f6ea..ea71114 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ GPP = /usr/bin/g++ -OPTS = -Wall -Wno-deprecated -std=c++17 -O2 -a.out: diccionariocuacs.o cuac.o fecha.o tablahash.o - $(GPP) $(OPTS) main.cpp tablahash.o cuac.o fecha.o diccionariocuacs.o +OPTS = -Wall -Wno-deprecated -g -std=c++17 +a.out: diccionariocuacs.o cuac.o fecha.o tablahash.o nodo.o arbol.o + $(GPP) $(OPTS) main.cpp tablahash.o cuac.o fecha.o diccionariocuacs.o nodo.o arbol.o fecha.o: fecha.cpp fecha.hpp $(GPP) $(OPTS) -c fecha.cpp @@ -15,8 +15,14 @@ tablahash.o: cuac.hpp fecha.hpp tablahash.cpp tablahash.hpp diccionariocuacs.o: diccionariocuacs.cpp diccionariocuacs.hpp cuac.hpp fecha.hpp tablahash.hpp $(GPP) $(OPTS) -c diccionariocuacs.cpp +nodo.o: nodo.cpp nodo.hpp fecha.hpp cuac.hpp + $(GPP) $(OPTS) -c nodo.cpp + +arbol.o: arbol.cpp nodo.hpp fecha.hpp cuac.hpp + $(GPP) $(OPTS) -c arbol.cpp + clean: - rm *.o a.out *.tar + rm *.o a.out tar: a.out tar cvf quacker.tar *.cpp *.hpp Makefile @@ -24,5 +30,5 @@ tar: a.out diff: a.out time ./a.out < entrada.in > salida - sleep 3 + sleep 1 diff salida salida.out -y --suppress-common-lines diff --git a/arbol.cpp b/arbol.cpp new file mode 100644 index 0000000..7583764 --- /dev/null +++ b/arbol.cpp @@ -0,0 +1,117 @@ +#include "arbol.hpp" + +// falta el date y el last + +Arbol::Arbol() { + raiz = new Nodo; +} + +Arbol::~Arbol() { + delete raiz; +} + +void Arbol::insertar(Cuac* ref){ + Nodo* actual = raiz; + Fecha f = ref -> get_fecha(); + string conv = f.conv(); // conv devuelve la fecha como un string en formato AAAA/MM/DD HH:MM:SS + + + for (size_t i = 0; i < conv.length(); i++) { + char digito = conv[i]; + if (actual -> consulta(digito) == nullptr) { + actual -> inserta(digito); + } + actual = actual -> consulta(digito); + + } + actual -> PonerMarca(); + actual -> PonerEnLista(ref); +} + +void Arbol::last(int N) { + if (raiz != nullptr) { + int contador = 0; + last_rec(raiz, N, contador); + cout << "Total: " << contador << " cuac" << endl; + } + +} + +void Arbol::last_rec(Nodo* nodo, int n, int &contador) { + if (nodo == nullptr || contador >= n) return; + last_rec(nodo -> getSig(), n, contador); + if (contador >= n) return; + list l = nodo -> getLista(); + if (!l.empty()) { + list::iterator it; + for (it = l.begin(); it != l.end() && contador < n; it++) { + cout << contador + 1 << ". "; + (*it) -> escribir(); + contador++; + } + } + last_rec(nodo -> getPtr(), n, contador); + +} + + +void Arbol::date(Fecha f1, Fecha f2) { + int contador = 0; + string fecha1 = f1.conv(); + string fecha2 = f2.conv(); + date_rec(raiz, fecha1, fecha2, "", contador); + cout << "Total: " << contador << " cuac" << endl; +} + +void Arbol::date_rec(Nodo* nodo, string f1, string f2, string actual, int& contador) { + /* if (nodo == nullptr) return; + if (nodo -> getCar() == ' ') { + date_rec(nodo -> getSig(), f1, f2, actual, contador); + return; + } + + while (nodo != nullptr) { + + if (nodo -> HayMarca()) { + list lista = nodo -> getLista(); + list::iterator it; + + for (it = lista.begin(); it != lista.end(); it++) { + contador++; + cout << contador << ". "; + (*it) -> escribir(); + } + } + string nueva = actual + nodo -> getCar(); + int nueva_len = nueva.length(); + if (nueva >= f1.substr(0, nueva_len) && nueva <= f2.substr(0, nueva_len)) { + date_rec(nodo -> getPtr(), f1, f2, nueva, contador); + } + nodo = nodo -> getSig(); + } */ + + if (nodo == nullptr) return; + // aplicamos la técnica de last_rec() para ir de derecha a izquierda + date_rec(nodo -> getSig(), f1, f2, actual, contador); // realmente se puede devolver el contador + if (nodo -> getCar() == ' ') { + date_rec(nodo -> getPtr(), f1, f2, actual, contador); + return; + } + + if (nodo -> HayMarca()) { + list lista = nodo -> getLista(); + list::iterator it; + + for (it = lista.begin(); it != lista.end(); it++) { + contador++; + cout << contador << ". "; + (*it) -> escribir(); + } + } + string nueva = actual + nodo -> getCar(); + int nueva_len = nueva.length(); + if (nueva >= f1.substr(0, nueva_len) && nueva <= f2.substr(0, nueva_len)) { + date_rec(nodo -> getPtr(), f1, f2, nueva, contador); + } + +} diff --git a/arbol.hpp b/arbol.hpp index 1e2bef7..22770cb 100644 --- a/arbol.hpp +++ b/arbol.hpp @@ -1,6 +1,7 @@ #pragma once #include "fecha.hpp" #include "nodo.hpp" +#include "cuac.hpp" #include @@ -10,7 +11,9 @@ class Arbol { public: Arbol(); ~Arbol(); - void insertar(); - void last(int N); + void insertar(Cuac *ref); + void last(int N); // recorrer el árbol de derecha a izquierda void date(Fecha f1, Fecha f2); -} + void last_rec(Nodo* nodo, int n, int &contador); + void date_rec(Nodo* nodo, string f1, string f2, string actual, int& contador); +}; diff --git a/cuac.cpp b/cuac.cpp index 6a442e4..62dcabc 100644 --- a/cuac.cpp +++ b/cuac.cpp @@ -33,11 +33,14 @@ bool Cuac::comparar(Cuac &c) { } else if (fecha.es_igual(c.fecha)) { if (mensaje == c.mensaje) { - return !(usuario < c.usuario); + return (usuario > c.usuario); } - return !(mensaje < c.mensaje); + return (mensaje > c.mensaje); } return false; } +Fecha& Cuac::get_fecha() { + return fecha; +} diff --git a/cuac.hpp b/cuac.hpp index c39dac3..0fb4d87 100644 --- a/cuac.hpp +++ b/cuac.hpp @@ -39,12 +39,12 @@ class Cuac { private: friend class TablaHash; string usuario; - Fecha fecha; string mensaje; - + Fecha fecha; public: void escribir(); void leer_pcuac(); void leer_mcuac(); bool comparar(Cuac &c); // falta implementar comparar!! ej. 004 + Fecha& get_fecha(); }; diff --git a/diccionariocuacs.cpp b/diccionariocuacs.cpp index 91c6ebf..71831e8 100644 --- a/diccionariocuacs.cpp +++ b/diccionariocuacs.cpp @@ -2,10 +2,11 @@ DiccionarioCuacs::DiccionarioCuacs(int m) { TablaHash th = TablaHash(m); + Arbol arbol = Arbol(); this -> tabla = th; } void DiccionarioCuacs::insertar(Cuac nuevo) { - Cuac *ref = tabla.insertar(nuevo); + Cuac* ref = tabla.insertar(nuevo); arbol.insertar(ref); } @@ -14,6 +15,19 @@ void DiccionarioCuacs::follow(string nombre){ tabla.consultar(nombre); } +void DiccionarioCuacs::last(int n) { + cout << "last " << n << endl; + arbol.last(n); +} + +void DiccionarioCuacs::date(Fecha f1, Fecha f2) { + cout << "date "; + f1.escribir(); + cout << " "; + f2.escribir(); + cout << '\n'; + arbol.date(f1, f2); +} int DiccionarioCuacs::elem() { return tabla.elem(); } diff --git a/diccionariocuacs.hpp b/diccionariocuacs.hpp index 513fa00..ec788f6 100644 --- a/diccionariocuacs.hpp +++ b/diccionariocuacs.hpp @@ -2,6 +2,7 @@ #include "fecha.hpp" #include "cuac.hpp" #include "tablahash.hpp" +#include "arbol.hpp" #include #include using namespace std; @@ -15,6 +16,8 @@ class DiccionarioCuacs { ~DiccionarioCuacs(); void insertar(Cuac nuevo); void follow(string nombre); + void last(int n); + void date(Fecha f1, Fecha f2); int elem(); }; diff --git a/fecha.cpp b/fecha.cpp index 6f35a62..9a00975 100644 --- a/fecha.cpp +++ b/fecha.cpp @@ -53,3 +53,9 @@ bool Fecha::es_menor(Fecha &f) { } } +std::string Fecha::conv() { + char buf[20]; + sprintf(buf, "%04d/%02d/%02d%02d:%02d:%02d", a, m, d, h, min, s); + return string(buf); +} + diff --git a/fecha.hpp b/fecha.hpp index ff4c00e..5c2d61e 100644 --- a/fecha.hpp +++ b/fecha.hpp @@ -1,5 +1,7 @@ #pragma once #include +#include +#include using namespace std; class Fecha { public: @@ -8,6 +10,7 @@ class Fecha { void escribir(); bool es_igual(Fecha &f); bool es_menor(Fecha &f); + string conv(); private: int d, m, a; int h, min, s; diff --git a/main.cpp b/main.cpp index d837f92..2411b6d 100644 --- a/main.cpp +++ b/main.cpp @@ -7,8 +7,6 @@ #include "tablahash.hpp" using namespace std; -// el número de cubetas tiene que cumplir B = 4r + 3 para todo r en N -// usamos 20003 porque queda cerca de 20000 // hay que redimensionar dinámicamente DiccionarioCuacs dic = DiccionarioCuacs(1000); @@ -35,12 +33,14 @@ void procesar_follow() { void procesar_last() { int n; cin >> n; + dic.last(n); } void procesar_date() { Fecha f1, f2; f1.leer(); f2.leer(); + dic.date(f1, f2); } int main() { @@ -57,6 +57,10 @@ int main() { procesar_follow(); } else if (comando == "exit") { break; + } else if (comando == "last") { + procesar_last(); + } else if (comando == "date") { + procesar_date(); } } diff --git a/nodo.cpp b/nodo.cpp index 329ed7a..14b8833 100644 --- a/nodo.cpp +++ b/nodo.cpp @@ -1,22 +1,83 @@ #include "nodo.hpp" +#include Nodo::Nodo(){ sig = nullptr; ptr = nullptr; + car = ' '; } Nodo::~Nodo() { delete sig; delete ptr; } -Nodo* consulta(char letra); -void inserta(char l); -bool HayMarca(); -void PonerMarca(); -void PonerEnLista(Cuac *ref) { - -} -list getLista() { - return lista; +Nodo* Nodo::consulta(char letra) { + // implementación tal cual del método consulta del tema 3 + Nodo* temp = this -> sig; + while (temp != nullptr){ + if (temp -> car == letra) { + return temp -> ptr; + } + temp = temp -> sig; + } + return nullptr; +} + +void Nodo::inserta(char l) { + + // implementación tal cual del método inserta del tema 3 + Nodo* temp = this; + while ((temp->sig != nullptr) && (temp -> sig -> car < l)) { + temp = temp -> sig; + } + + if ((temp -> sig != nullptr) && (temp -> sig -> car == l)) { + return; + } + + Nodo* nuevo = new Nodo; + nuevo -> car = l; + nuevo -> sig = temp -> sig; + temp -> sig = nuevo; + nuevo -> ptr = new Nodo; + +} + +bool Nodo::HayMarca() { + return this -> car == '$'; +} + +void Nodo::PonerMarca() { + this -> car = '$'; +} + +void Nodo::PonerEnLista(Cuac *ref) { + if (HayMarca()) { + + list::iterator it; + for (it = lista.begin(); it != lista.end(); it++) { + if (!ref -> comparar(**it)) { + lista.insert(it, ref); + return; + } + } + lista.push_back(ref); + } +} + +list Nodo::getLista() { + return this -> lista; +} + +Nodo* Nodo::getSig() { + return this -> sig; +} + +Nodo* Nodo::getPtr() { + return this -> ptr; +} + +char Nodo::getCar() { + return this -> car; } diff --git a/nodo.hpp b/nodo.hpp index 5b5b304..e8c920f 100644 --- a/nodo.hpp +++ b/nodo.hpp @@ -10,7 +10,7 @@ class Nodo { char car; Nodo *sig, *ptr; Fecha f; - list lista; + list lista; // almacena todos los cuacs de una fecha public: Nodo(); @@ -21,4 +21,7 @@ class Nodo { void PonerMarca(); void PonerEnLista(Cuac *ref); list getLista(); + Nodo* getSig(); + Nodo* getPtr(); + char getCar(); }; diff --git a/tablahash.cpp b/tablahash.cpp index 470b6a7..091d457 100644 --- a/tablahash.cpp +++ b/tablahash.cpp @@ -11,17 +11,18 @@ TablaHash::TablaHash() { TablaHash::~TablaHash() { } -void TablaHash::insertar(Cuac nuevo) { +Cuac* TablaHash::insertar(Cuac nuevo) { int pos = h(nuevo.usuario); list::iterator it = lista[pos].begin(); while (it != lista[pos].end() && nuevo.comparar(*it)){ it++; } if (it==lista[pos].end() || !nuevo.comparar(*it)) { - lista[pos].insert(it--, nuevo); - it++; + lista[pos].insert(it, nuevo); + it--; + nElem++; } - nElem++; + return &*it; } void TablaHash::consultar(string clave) { diff --git a/tablahash.hpp b/tablahash.hpp index d1c84b1..5f79ec6 100644 --- a/tablahash.hpp +++ b/tablahash.hpp @@ -14,20 +14,12 @@ class TablaHash { list *lista; public: - // implementar dispersión abierta - // tamaño variable (memoria dinámica) - // probar funciones de dispersión - // suma posicional - // posicional por trozos - // extracción - // etc TablaHash(); TablaHash(int M); ~TablaHash(); - void insertar(Cuac nuevo); + Cuac* insertar(Cuac nuevo); void consultar(string nombre); unsigned int h(string clave); - // unsigned int h_spt(string clave); int elem() { return nElem; } };