Es vol dotar una versió simplificada de la pràctica amb una nova operació de consulta amb la qual es pugui obtenir una llista de les tasques que compleixin una certa expressió booleana d’etiquetes i, a més, continguin un cert string en el títol. El format de la nova consulta és una línia que comença per ?, seguida d’una expressió booleana i finalitzada per un string. Per exemple,
? ((#salut,#esport).(#lectura,#escriptura)) anar
és una consulta de les tasques que contenen #salut o #esport i #lectura o #escriptura i, addicionalment, tenen el string anar en el títol.
La pràctica sobre la qual cal afegir aquesta operació conté una classe Agenda, que organitza tasques i etiquetes, i una classe Tasca, amb mètodes per llegir i escriure tasques, per consultar el títol o l’hora d’una tasca i per comprovar si una tasca conté una etiqueta determinada. Tant els atributs com l’especificació de les operacions públiques de les dues classes els trobareu a l’apartat Public files del Jutge.
Es demana un mètode per a la classe Agenda amb l’especificació següent:
void Agenda::tasques(string &expressio, const string &mot); // Pre: "expressio" és una expressió booleana d'etiquetes amb format correcte, // "mot" és un string // Post: s'han escrit pel canal estàndard de sortida totes les tasques del p.i. tals que: // - les etiquetes associades satisfan l'expressió booleana "expressio" // - el seu títol conté el substring "mot" // ordenades cronològicament
Per implementar el mètode tasques, podeu fer-ho d’una de dues maneres possibles. La primera és recorrent les tasques una per una i comprovant si compleixen l’expressió boolena. En aquest cas, heu d’implementar el mètode públic següent:
bool Tasca::compleix_expressio(string &e); // Pre: e és una expressió booleana d'etiquetes amb format correcte // Post: cert si i només si les etiquetes del p.i. compleixen l'expressió boolena e
L’altra possibilitat és generar recursivament una llista (o vector) de les tasques que compleixen les subexpressions, i fer la reunió o la intersecció segons convingui. Si trieu aquesta solució, heu d’implementar el mètode privat següent:
vector<int> Agenda::compleixen_expressio(string &e); // Pre: e és una expressió booleana d'etiquetes amb format correcte // Post: retorna les posicions del vector t del p.i. de totes les tasques que compleixen // l'expressió booleana e, en ordre creixent
El mètode anterior pot fer ús dels mètodes privats reunió i intersecció que trobareu especificats en el fitxer agenda.hh.
Amb qualsevol dels dos mètodes anteriors, necessitareu extreure substrings a partir d’un string determinat. Podeu fer-ho mitjançant el mètode substr() de la classe string. Donat un string x i dos enters i, j, x.substr(i) retorna el sufix de x que comença en la posició i, mentre que x.substr(i,j) retorna el substring de mida j que comença en la posició i (les posicions comencen per la 0).
Per comprovar si un string x conté o no un substring y, és recomanable declarar un enter i assignar-li el resultat de x.find(y). D’aquesta manera, si es troba y en x, l’enter contindrà la posició de x on comença l’aparició de y; si no es troba, l’enter valdrà −1. (Si es fes sense definir prèviament l’enter, comparar directament el resultat de x.find(y) amb un altre valor podria no donar el resultat esperat.)
Observació
Heu de lliurar un fitxer solucio.cc amb una implementació eficient del mètode tasques (de la classe Agenda) i, a més, un dels dos següents:
El format del fitxer solucio.cc ha de ser el següent:
#include "agenda.hh" void Agenda::tasques(string &expressio, const string &mot) { // codi de la implementació } /* Treieu les marques de comentari si implementeu aquest mètode bool Tasca::compleix_expressio(string &e) { // codi de la implementació } */ /* Treieu les marques de comentari si implementeu aquest mètode vector<int> Agenda::compleixen_expressio(string &e) { // codi de la implementació } */
Copieu aquesta plantilla en el vostre solucio.cc i completeu-la, deixant com a comentari o eliminant el mètode que no implementeu. El vostre solucio.cc no pot contenir la implementació d’altres operacions de les classes, però podeu afegir-hi funcions o procediments auxiliars externs a les classes.
Podeu descomprimir el fitxer .tar que us proporcionem a l’apartat Public files del Jutge mitjançant la comanda
tar -xvf nom_fitxer.tar
Aquest material addicional consisteix en els fitxers següents: