Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar 2010-2011 21 juni 2011 **BELANGRIJK** 1. Lees eerst de volledige opgave (inclusief de hints/opmerkingen)! 2. In dit deel komt enkel C++ aan bod (geen C) 3. Schrijf je naam, stamnummer en richting bovenaan elk cpp bestand. 4. Je mag de gegeven header bestanden NIET aanpassen! Doe je dit toch, dan verlies je punten. De laatste twee vragen in deel B. HashTabel worden enkel op papier neergepend, niet geïmplementeerd. 5. Bestudeer aandachtig de gegeven header bestanden; ze bevatten extra informatie over de te implementeren functies en de werking van de code. 6. De main methode hoeft in principe niet aangepast te worden, maar dit is wel toegelaten. 7. Kladpapier vind je achteraan 8. Veel succes! Programmeren in C++ [op 12 punten van de 20] Ontwerp van een gepersonaliseerde, tag-gebaseerde URL databank Doelstelling van deze opgave is een applicatie om voor verschillende gebruikers URLs op te slaan, zodat men ze later gemakkelijk kan terugvinden op basis van tags, die aan elke URL toegekend zijn. Voorbeelden van tags aan een bepaalde URL zijn bijvoorbeeld: "minerva", "CPP ref", "C++", m.a.w. de tags zijn strings met tekstuele beschrijving over de URL in kwestie. De URLs worden bijgehouden per gebruiker en gesorteerd op tags, zodat men voor een gegeven tag zeer snel de URLs met die tag kan opzoeken. Er wordt gebruik gemaakt van een binaire zoekboom en een hashtabel, beiden template klassen. In Deel A van de opgave komt enkel de binaire zoekboom aan bod, in Deel B enkel de hashtabel en in Deel C worden deze template klassen geïnstantieerd in de TagDatabase klasse. A. Binaire Zoekboom [1.5/12] De binaire zoekboom die hier gebruikt wordt mapt sleutels van een willekeurig type op pointers naar waarden van een willekeurig type. Deze binaire zoekboom ziet er schematisch als volgt uit: Naam:.. blz. 1
Gegeven de header BinarySearchTree.h,en de implementaties BinarySearchTree.cpp, template_instantiations.cpp en main.cpp. Gevraagd is een implementatie te schrijven voor de methode insert(const K& key, V* value)uit BinarySearchTree. Deze voegt een nieuw element met opgegeven sleutel en waarde op de juiste plaats toe in de boom. [1.5 punt] Je kan je code testen via de testbst() oproep in main.cpp. B. HashTabel [5.5/12] De hashtabel die hier gebruikt wordt associeert strings met een waarde van een willekeurig type. Deze hashtabel bestaat uit een array van lijsten van HT_Entry objecten, die op hun beurt bestaan uit een string en een pointer naar de waarde geassocieerd met die string. Deze hashtable gebruikt separate chaining; dit betekent dat alle elementen waarvan de sleutel dezelfde hashwaarde hebben, in dezelfde lijst worden opgeslagen. De positie van die lijst wordt uiteraard bepaald door de hashfunctie uit te voeren op de betreffende sleutel en af te stemmen op de correcte grootte van de tabel. Verder worden een aantal extra waarden bijgehouden, zoals het aantal sleutel-waarde paren aanwezig in de hashtabel, het aantal plaatsen voorzien in de tabel, en de huidige load factor. Ook zijn er 2 constanten gedefinieerd: de default grootte van de tabel (DEFAULT_CAPACITY) en de maximale waarde die de load factor mag aannemen voor er een rehash() operatie wordt uitgevoerd (MAX_LOAD_FACTOR). De load factor is gedefinieerd als het aantal sleutel-waarde paren aanwezig in de hashtabel, gedeeld door de capaciteit van de hashtabel. Naam:.. blz. 2
De datastructuur ziet er schematisch als volgt uit: Gegeven de header HashTable.h en de implementaties HashTable.cpp, template_instantiations.cpp en main.cpp. Gevraagd: vul HashTable.cpp verder aan: get [1.5 punt]: geeft een lijst terug met pointers naar de waarden die overeenstemmen met de opgegeven sleutel remove [2 punten]: verwijdert een element uit de hashtabel waarvan de sleutel overeenstemt met de opgegeven sleutel. Indien er meerdere elementen zijn met die sleutel wordt het eerste dergelijke element verwijderd. Uiteraard moeten andere elementen waarvan de sleutel dezelfde hashwaarde heeft als de sleutel van het te verwijderen element na verwijdering nog steeds vindbaar zijn. Deze methode geeft ook de pointer terug naar (de waarde van) het verwijderde element. Er wordt geen rehash()operatie uitgevoerd indien de load factor te klein wordt. rehash [2 punten]: verdubbelt de grootte van de hashtabel, en zorgt ervoor dat alle voorheen aanwezige elementen beschikbaar blijven. Wordt opgeroepen wanneer MAX_LOAD_FACTOR overschreden wordt. Geen dubbel werk: maak hierbij gebruik van bestaande functies in HashTable.cpp. Hoe zou je de header HashTable.h moeten aanpassen om een HashTable object ht te kunnen doorgeven aan een outputstream (e.g. cout<<ht;)? Beschrijf hieronder je aanpassingen, voer deze niet uit in de code! [0.5 punt] Naam:.. blz. 3
Hoe zou je de cpp file HashTable.cpp moeten aanpassen om een HashTable object ht te kunnen doorgeven aan een outputstream (e.g. cout<<ht;)? Beschrijf hieronder, voer niet uit in code! [0.5 punt] Je kan je code testen door de testht() oproep in main.cpp uit commentaar te halen. Hints: Zie ook de header file HashTable.h! Gebruik de methode unsigned int hash(const string& key) uit HashTable.cpp! Het bereik van deze functie is niet afgestemd op de grootte van de hashtabel en geeft met andere woorden een willekeurige positieve waarde terug. Vergeet niet de variabelen numberofentries, capacity en loadfactor aan te passen waar nodig. C. TagDatabase [5/12] De TagDatabase klasse gebruikt een template instantiatie van de 2 voorgaande klassen om per gebruiker URLs, geannoteerd met tags, op te slaan. Deze klasse houdt een zoekboom bij waarbij de gebruikers(namen) gemapt worden op een hashtabel. Deze hashtabel mapt dan tags op de URLs waarmee ze geassocieerd worden door die gebruiker. Zowel gebruikersnamen als tags en URLs worden voorgesteld door middel van string objecten. URLs kunnen uiteraard meer dan 1 keer voorkomen als waarde. Verder houdt de TagDatabase ook een set bij van alle gebruikers. Schematisch ziet de datastructuur er als volgt uit: Naam:.. blz. 4
Gegeven de headers BinarySearchTree.h, HashTable.h, TagDatabase.h en de implementaties BinarySearchTree.cpp, HashTable.cpp, TagDatabase.cpp, template_instantiations.cpp en main.cpp. Gevraagd: vul TagDatabase.cpp verder aan: addurl[2.5 punten]: voegt de opgegeven URL toe aan de verzameling van tag- URL mappings voor de opgegeven gebruiker. Dit impliceert dat voor elke opgegeven tag deze URL moet toegevoegd worden in de list in overeenstemming met de hashwaarde van de tag. Indien de gebruiker nog niet bestaat moet deze aangemaakt worden. Vergeet de set niet aan te passen! geturls[2 punten]: geeft een set terug die alle URLs van de opgegeven gebruiker bevat die met de 2 opgegeven tags tegelijk overeenstemmen. destructor [0.5 punten]: geeft al het geheugen vrij dat door de TagDatabase wordt ingenomen Je kan je code testen door de testtdb() oproep in main.cpp uit commentaar te halen. Veel succes! Naam:.. blz. 5
KLADPAPIER: Naam:.. blz. 6