Implementa la classe Finder
, que té la següent especificació:
template <class T> class Finder { public: Finder(); void add(const T *t); void update(const T *t); void remove(const T *t); std::set<const T *> query(pro2::Rect qrect) const; };
La classe és un contenidor de punters a objectes de tipus T
, i el tipus T
ha de ser una classe amb un mètode get_rect
, que obtingui el "rectangle de l’objecte", amb la següent declaració:
pro2::Rect get_rect() const;
El rectangle és una tupla amb 4 enters left
, top
, right
, bottom
. El Finder
ha de poder associar cada objecte amb el rectangle que ocupa, de tal manera que es puguin fer consultes. Aquestes consultes, amb el mètode query
, reben un rectangle qrect
i ens retornen tots els punters a objectes de tipus T
tals que si demanem el seu rectangle amb get_rect
, aquest intersecta amb qrect
. Si qrect
representa una finestra, query
permet localitzar aquells objectes que són visibles a través de la finestra (ja sigui totalment o en part).
L’objectiu és que Finder
pugui emmagatzemar molts milers d’objectes, però si aquests estan distribuits per tot l’espai bidimensional, una consulta a una zona petita de l’espai només ha de retornar uns pocs objectes.
Per acotar el problema, es defineixen els següents tamanys límit:
Intersecció de rectangles
Els rectangles tenen coordenades enteres, i el Finder
fa la suposició que les coordenades límit d’un rectangle estan incloses en el propi rectangle, de manera que dos rectangles (en ordre left top right bottom) com 0 0 10 10
i 10 10 30 50
intersecten just al punt (10, 10), que en primer cas és la cantonada de baix a la dreta i en el segon cas és la cantonada de dalt a l’esquerra.
Codi disponible
Per poder fer el programa més còmodament, el codi públic d’aquest problema (la icona del gatet) proporciona:
Makefile
que compila el programa amb només fer make
.
.vscode
que permet compilar i depurar només prement F5.
geometry.hh
, que defineix les tuples Pt
i Rect
, que fa servir la majoria d’altres classes.
TestObject
, un objecte de prova que té el mètode get_rect
i es pot posar al Finder
.
Finder
.
Observació
Per entregar, descarrega el codi públic, i implementa o afegeix el fitxer finder.hh
. Cal enviar un .tar
només amb el fitxer finder.hh
.
Entrada
El programa principal ja gestiona l’entrada. Aquesta conté 5 tipus de "comandes", cadascuna en una línia apart:
+
, per afegir un objecte, amb l’id
(un string
) i les seves coordenades;
-
, per esborrar un objecte, donat l’id
;
=
, per actualitzar un objecte, donat l’id
i les noves coordenades;
?
, per consultar una zona, donades les coordenades d’un rectangle;
0
, per esborrar el Finder
i crear-ne un de nou.
Totes les coordenades de rectangles segueixen l’ordre left, top, right, bottom.
El programa principal defineix una classe FinderTester
que s’ocupa de relacionar els id
s amb els punters als objectes i en un fitxer apart (test-object.hh
) es defineix una classe TestObject
mínima que serveix per fer les proves.
Sortida
La sortida és el resultat de les consultes (les altres comandes no produeixen sortida). D’això també s’encarrega el programa principal. Quan una consulta no retorna objectes, s’escriu "empty
", i quan hi ha objectes, es mostren els seus id
s per ordre lexicogràfic.
Input
? 0 0 1 1 + a 0 0 1 1 ? 0 0 0 0 + b 2 2 3 3 ? 1 1 1 1 ? 1 1 2 2 ? 2 2 3 3 ? 4 4 5 5
Output
empty objs: a objs: a objs: a b objs: b empty