This commit is contained in:
2025-12-01 23:41:00 +01:00
parent 1c1e22b1df
commit 9bc260a750
14 changed files with 254 additions and 38 deletions

View File

@@ -1,7 +1,7 @@
GPP = /usr/bin/g++ GPP = /usr/bin/g++
OPTS = -Wall -Wno-deprecated -std=c++17 -O2 OPTS = -Wall -Wno-deprecated -g -std=c++17
a.out: diccionariocuacs.o cuac.o fecha.o tablahash.o 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 $(GPP) $(OPTS) main.cpp tablahash.o cuac.o fecha.o diccionariocuacs.o nodo.o arbol.o
fecha.o: fecha.cpp fecha.hpp fecha.o: fecha.cpp fecha.hpp
$(GPP) $(OPTS) -c fecha.cpp $(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 diccionariocuacs.o: diccionariocuacs.cpp diccionariocuacs.hpp cuac.hpp fecha.hpp tablahash.hpp
$(GPP) $(OPTS) -c diccionariocuacs.cpp $(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: clean:
rm *.o a.out *.tar rm *.o a.out
tar: a.out tar: a.out
tar cvf quacker.tar *.cpp *.hpp Makefile tar cvf quacker.tar *.cpp *.hpp Makefile
@@ -24,5 +30,5 @@ tar: a.out
diff: a.out diff: a.out
time ./a.out < entrada.in > salida time ./a.out < entrada.in > salida
sleep 3 sleep 1
diff salida salida.out -y --suppress-common-lines diff salida salida.out -y --suppress-common-lines

117
arbol.cpp Normal file
View File

@@ -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<Cuac*> l = nodo -> getLista();
if (!l.empty()) {
list<Cuac*>::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<Cuac*> lista = nodo -> getLista();
list<Cuac*>::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<Cuac*> lista = nodo -> getLista();
list<Cuac*>::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);
}
}

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "fecha.hpp" #include "fecha.hpp"
#include "nodo.hpp" #include "nodo.hpp"
#include "cuac.hpp"
#include <iostream> #include <iostream>
@@ -10,7 +11,9 @@ class Arbol {
public: public:
Arbol(); Arbol();
~Arbol(); ~Arbol();
void insertar(); void insertar(Cuac *ref);
void last(int N); void last(int N); // recorrer el árbol de derecha a izquierda
void date(Fecha f1, Fecha f2); 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);
};

View File

@@ -33,11 +33,14 @@ bool Cuac::comparar(Cuac &c) {
} }
else if (fecha.es_igual(c.fecha)) { else if (fecha.es_igual(c.fecha)) {
if (mensaje == c.mensaje) { if (mensaje == c.mensaje) {
return !(usuario < c.usuario); return (usuario > c.usuario);
} }
return !(mensaje < c.mensaje); return (mensaje > c.mensaje);
} }
return false; return false;
} }
Fecha& Cuac::get_fecha() {
return fecha;
}

View File

@@ -39,12 +39,12 @@ class Cuac {
private: private:
friend class TablaHash; friend class TablaHash;
string usuario; string usuario;
Fecha fecha;
string mensaje; string mensaje;
Fecha fecha;
public: public:
void escribir(); void escribir();
void leer_pcuac(); void leer_pcuac();
void leer_mcuac(); void leer_mcuac();
bool comparar(Cuac &c); // falta implementar comparar!! ej. 004 bool comparar(Cuac &c); // falta implementar comparar!! ej. 004
Fecha& get_fecha();
}; };

View File

@@ -2,10 +2,11 @@
DiccionarioCuacs::DiccionarioCuacs(int m) { DiccionarioCuacs::DiccionarioCuacs(int m) {
TablaHash th = TablaHash(m); TablaHash th = TablaHash(m);
Arbol arbol = Arbol();
this -> tabla = th; this -> tabla = th;
} }
void DiccionarioCuacs::insertar(Cuac nuevo) { void DiccionarioCuacs::insertar(Cuac nuevo) {
Cuac *ref = tabla.insertar(nuevo); Cuac* ref = tabla.insertar(nuevo);
arbol.insertar(ref); arbol.insertar(ref);
} }
@@ -14,6 +15,19 @@ void DiccionarioCuacs::follow(string nombre){
tabla.consultar(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() { int DiccionarioCuacs::elem() {
return tabla.elem(); return tabla.elem();
} }

View File

@@ -2,6 +2,7 @@
#include "fecha.hpp" #include "fecha.hpp"
#include "cuac.hpp" #include "cuac.hpp"
#include "tablahash.hpp" #include "tablahash.hpp"
#include "arbol.hpp"
#include <string> #include <string>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@@ -15,6 +16,8 @@ class DiccionarioCuacs {
~DiccionarioCuacs(); ~DiccionarioCuacs();
void insertar(Cuac nuevo); void insertar(Cuac nuevo);
void follow(string nombre); void follow(string nombre);
void last(int n);
void date(Fecha f1, Fecha f2);
int elem(); int elem();
}; };

View File

@@ -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);
}

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <string>
#include <cstdio>
using namespace std; using namespace std;
class Fecha { class Fecha {
public: public:
@@ -8,6 +10,7 @@ class Fecha {
void escribir(); void escribir();
bool es_igual(Fecha &f); bool es_igual(Fecha &f);
bool es_menor(Fecha &f); bool es_menor(Fecha &f);
string conv();
private: private:
int d, m, a; int d, m, a;
int h, min, s; int h, min, s;

View File

@@ -7,8 +7,6 @@
#include "tablahash.hpp" #include "tablahash.hpp"
using namespace std; 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 // hay que redimensionar dinámicamente
DiccionarioCuacs dic = DiccionarioCuacs(1000); DiccionarioCuacs dic = DiccionarioCuacs(1000);
@@ -35,12 +33,14 @@ void procesar_follow() {
void procesar_last() { void procesar_last() {
int n; int n;
cin >> n; cin >> n;
dic.last(n);
} }
void procesar_date() { void procesar_date() {
Fecha f1, f2; Fecha f1, f2;
f1.leer(); f1.leer();
f2.leer(); f2.leer();
dic.date(f1, f2);
} }
int main() { int main() {
@@ -57,6 +57,10 @@ int main() {
procesar_follow(); procesar_follow();
} else if (comando == "exit") { } else if (comando == "exit") {
break; break;
} else if (comando == "last") {
procesar_last();
} else if (comando == "date") {
procesar_date();
} }
} }

View File

@@ -1,22 +1,83 @@
#include "nodo.hpp" #include "nodo.hpp"
#include <cassert>
Nodo::Nodo(){ Nodo::Nodo(){
sig = nullptr; sig = nullptr;
ptr = nullptr; ptr = nullptr;
car = ' ';
} }
Nodo::~Nodo() { Nodo::~Nodo() {
delete sig; delete sig;
delete ptr; delete ptr;
} }
Nodo* consulta(char letra); Nodo* Nodo::consulta(char letra) {
void inserta(char l); // implementación tal cual del método consulta del tema 3
bool HayMarca(); Nodo* temp = this -> sig;
void PonerMarca(); while (temp != nullptr){
void PonerEnLista(Cuac *ref) { if (temp -> car == letra) {
return temp -> ptr;
} }
list<Cuac*> getLista() { temp = temp -> sig;
return lista; }
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<Cuac*>::iterator it;
for (it = lista.begin(); it != lista.end(); it++) {
if (!ref -> comparar(**it)) {
lista.insert(it, ref);
return;
}
}
lista.push_back(ref);
}
}
list<Cuac*> Nodo::getLista() {
return this -> lista;
}
Nodo* Nodo::getSig() {
return this -> sig;
}
Nodo* Nodo::getPtr() {
return this -> ptr;
}
char Nodo::getCar() {
return this -> car;
} }

View File

@@ -10,7 +10,7 @@ class Nodo {
char car; char car;
Nodo *sig, *ptr; Nodo *sig, *ptr;
Fecha f; Fecha f;
list<Cuac*> lista; list<Cuac*> lista; // almacena todos los cuacs de una fecha
public: public:
Nodo(); Nodo();
@@ -21,4 +21,7 @@ class Nodo {
void PonerMarca(); void PonerMarca();
void PonerEnLista(Cuac *ref); void PonerEnLista(Cuac *ref);
list<Cuac*> getLista(); list<Cuac*> getLista();
Nodo* getSig();
Nodo* getPtr();
char getCar();
}; };

View File

@@ -11,17 +11,18 @@ TablaHash::TablaHash() {
TablaHash::~TablaHash() { TablaHash::~TablaHash() {
} }
void TablaHash::insertar(Cuac nuevo) { Cuac* TablaHash::insertar(Cuac nuevo) {
int pos = h(nuevo.usuario); int pos = h(nuevo.usuario);
list<Cuac>::iterator it = lista[pos].begin(); list<Cuac>::iterator it = lista[pos].begin();
while (it != lista[pos].end() && nuevo.comparar(*it)){ while (it != lista[pos].end() && nuevo.comparar(*it)){
it++; it++;
} }
if (it==lista[pos].end() || !nuevo.comparar(*it)) { if (it==lista[pos].end() || !nuevo.comparar(*it)) {
lista[pos].insert(it--, nuevo); lista[pos].insert(it, nuevo);
it++; it--;
nElem++;
} }
nElem++; return &*it;
} }
void TablaHash::consultar(string clave) { void TablaHash::consultar(string clave) {

View File

@@ -14,20 +14,12 @@ class TablaHash {
list<Cuac> *lista; list<Cuac> *lista;
public: 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();
TablaHash(int M); TablaHash(int M);
~TablaHash(); ~TablaHash();
void insertar(Cuac nuevo); Cuac* insertar(Cuac nuevo);
void consultar(string nombre); void consultar(string nombre);
unsigned int h(string clave); unsigned int h(string clave);
// unsigned int h_spt(string clave);
int elem() { return nElem; } int elem() { return nElem; }
}; };