// II17 2005-06 // Tema2/Problema-Region/Region.cpp // 07-12-2005, 08-12-2005 #include "Region.h" Region::Region () : lista(NULL) { } Region::Nodo::Nodo (Punto2D p, Nodo *s) : punto(p), siguiente(s) { } bool Region::PertenecePunto (Punto2D p) const { for (Nodo * aux = lista; aux != NULL; aux = aux->siguiente) if (aux->punto == p) return true; return false; } void Region::InsertarPunto (Punto2D p) { if (!PertenecePunto(p)) lista = new Nodo (p, lista); } void Region::Vaciar(){ Nodo *aux; while(lista != NULL){ aux = lista; lista = aux->siguiente; delete aux; } } Region::Region (Punto2D p) { lista = new Nodo (p, NULL); } // Otra solucion: // Region::Region (Punto2D p) : lista(NULL) { // InsertarPunto(p); //} Region::Region (const Region & r) : lista(NULL) { *this = r; } Region & Region::operator= (const Region & r) { if(this != &r) { Vaciar(); for (Nodo * aux = r.lista; aux != NULL; aux = aux->siguiente) // Aqui podriamos hacer: // InsertarPunto(aux->punto); // pero entonces el coste de r1 = r2 seria O(|r1|+|r2|^2) en vez // de O(|r1|+|r2|), porque para cada punto de r2 se llamaria // innecesariamente a PertenecePunto. lista = new Nodo (aux->punto, lista); // Asi los puntos quedan en la lista en el orden inverso al de r. // Suponemos que en este problema eso es aceptable. } return *this; } Region::~Region() { Vaciar(); } Region & Region::operator+= (const Region & r) { // Aqui podriamos hacer: // return *this = *this + r; // si implementasemos el operator+ sin usar el operator+=, // pero con eso estariamos haciendo una copia de los puntos de *this // que evitamos si lo hacemos asi: for (Nodo * aux = r.lista; aux != NULL; aux = aux->siguiente) InsertarPunto(aux->punto); return *this; // EJERCICIO: - Piensa cual es el coste temporal de r1 += r2 con esta // solucion en funcion de |r1| y |r2| // - Cambia la solucion para reducir ese coste a O(|r1||r2|+|r2|) // suponiendo que r2 no tiene puntos repetidos (con lo que no hace // falta comparar los de r2 entre si). } Region operator+ (const Region & r1, const Region & r2) { Region resultado = r1; resultado += r2; return resultado; } ostream & operator<< (ostream & flujo, const Region & r) { flujo << '{'; for (Region::Nodo * aux = r.lista; aux != NULL; aux = aux->siguiente) { flujo << aux->punto; if (aux->siguiente != NULL) flujo << ','; } flujo << '}'; return flujo; } istream & operator>> (istream & flujo, Region & r) { // Suponemos, como dice el enunciado, que no hay errores en la // entrada y hay al menos un punto. char separador; Punto2D punto; r.Vaciar(); flujo >> separador; do { flujo >> punto >> separador; r.InsertarPunto(punto); // Asi los puntos quedan en la lista en el orden inverso al de la entrada. // Suponemos que en este problema eso es aceptable. } while (separador != '}'); return flujo; }