Table of Contents

Tema 2 - The Library of HashBabel

Responsabili:

Actualizări

Obiective

Introducere

Este inceptul secolului al XVII-lea si un nou concept apare in randul oamenilor intelectuali: un manuscris menit sa realizeze conexiunea dintre doua limbaje diferite. Hipsterii vremii i-au spus heșteibăl sau heșmep, dar pana la urma a devenit social acceptat termenul de dictionar.

Cetateni din toate clasele sociale se inghesuie, mai ceva ca la tigai, sa puna mana pe un dictionar, asa ca administratia orasului se gandeste sa centralizeze treaba.

Pentru ca esti invatatul orasului (ai zis o gluma cu Da Vinci la un party), primesti cel mai important job: administrarea unei biblioteci unde oamenii pot veni sa imprumute carti (dictionare).

Cerintă

Pentru rezolvarea temei, va trebui sa implementati doua componente:

Structura Hashtable

Trebuie sa implementati o structura de tip dictionar care sa respecte urmatoarele restrictii:

Hashtable-ul trebuie sa aiba implementate cel putin urmatoarele functionalitati (precum modelul din laborator):

* Put(key, value)
* Remove(key)
* Get(key)
* Has_Key(key)

Resizing

Atunci cand un hashtable este foarte “aglomerat”, complexitatea unei operii devine prea mare pentru functionalitati care ar trebuie sa aibe O(1) pe caz general. De ex: daca avem un hashtable cu 10 bucket-uri (implementare prin chaining) si adaugam 1000 de intrari (perechi key-value), inseamna ca pe caz general fiecare operatie trebuie sa faca 100 de pasi (cate elemente sunt in medie intr-un bucket). Pentru a rezolva aceasta problema, adaugam mecanismul de resize.

Notam cu E numarul de elemente (intrari) din hashtable si cu B numarul de bucketuri.

load_factor = E / B

Daca load_factor > 1, inseamna ca structura este prea aglomerata, prin urmare se realizeaza operatia de resize (pentru tema am ales valoarea 1 ca limita superioara, insa aceesta nu este standard). NU va trebui sa implementati si cazul in care load_factor este prea mic.

Pasi resize

Nu aveti voie sa folositi o valoare mare ca dimensiune initiala a vectorului de bucket-uri, astfel incat sa nu se activeze niciodata mecanismul de resizing. Dimenensiunea initiala trebuie sa fie un numar natural cel mult egal cu 10.

Se garanteaza ca testele sunt suficient de mari astfel incat sa verifice implementarea mecanismului de resizing (daca nu este implementat, operatiile vor dura prea mult timp).

Biblioteca

Locuitorii orasului, cei ce intretin aceasta biblioteca, ajutand-o sa se dezvolte zilnic, vor fi numiti in continuare useri. Folosind implementarea de mai sus, va trebui sa simulati un sistem de gestiune al unei biblioteci ce suporta interactiunea cu utilizatori, prin citirea unui numar de comenzi. Acestea se opresc atunci cand ultima comanda citita are valoare “EXIT”.

Dictionar

In continuare vom numi dictionar (sau carte) o colectie de definitii. O definitie este o pereche formata din def_key si def_val. De exemplu, pentru un dictionar cu numele “Dictionar Roman-Englez”, o posibila reprezentare a colectiei ar putea fi (unde o intrare este o pereche de forma def_key:def_val) :

Spre deosebire de un dictionar traditional, intrarile nu trebuie sortate dupa cheie. Imaginea de mai sus nu reprezinta asezarea efectiva in memorie. Atat def_key cat si val_key sunt siruri de caractere formate dintr-un singur cuvant. Trebuie sa implementati o baza de date ce simuleaza rafturile bibliotecii, pe care se afla carti de tipul dictionar.

Atat intreaga biblioteca, cat si fiecare carte in parte, trebuie implementate folosind structura de hashtable definita anterior.

Comenzi biblioteca / dictionar

O carte poate fi adaugata sau stearsa din biblioteca. De asemenea, aflandu-ne in plin proces de dezvoltare, intr-o carte se poate adauga sau sterge o definitie.

Comanda adauga cartea citita in biblioteca (daca exista o carte cu acelasi nume atunci se va actualiza valoarea acesteia: va avea loc operatia de update). Numele cartii poate contine mai multe cuvinte si va fi delimitat de caracterul ' ” '. Lungimea totala a lui book_name NU depaseste 40 de caractere. Def_number reprezinta numarul de definitii din carte. Pe urmatoarele def_number linii se gasesc perechi de forma (def_key, val_key). Atat def_key cat si val_key sunt stringuri ce NU au lungimea mai mare de 20 de caractere.

Name:book_name Rating:book_rating Purchase:book_purchases

Comenzi useri

Pentru gestionarea userilor in memorie, se va folosi, de asemenea, un hashtable (aceeasi structura generica folosita pentru biblioteca). Userul poate imprumuta, returna sau pierde o carte. De asemenea, la returnarea fiecari carti, acesta ofera si un calificativ (similar GoodReads sau IMDb).

In plus, zilele acestea, in oras se va desfasura o competitie de lectura, pentru a determina cei mai etici cititori. La finalul acesteia, se va afisa clasamentul userilor si clasamentul celor mai populare carti.

Pentru a fi departajati, fiecare user va avea asociat un punctaj. La inscrierea in sistem, toti primesc 100p. Atunci cand acestia imprumuta o carte, vor fi nevoiti sa precizeze si un numar de zile pana la returnare. Daca un user inapoieaza o carte mai repede decat termenul limita, numarul de puncte creste. Daca intarzie cu returnarea cartii sau pierde cartea, numarul de puncte scade.

Un user care ajunge sa aiba punctaj negativ este banat din sistem. Un user banat nu mai are voie sa interactioneze cu biblioteca si nici nu va aparea in clasamentul final. Un user banat nu are voie sa fie reintrodus in sistem.

Sfarsitul comenzilor

Atunci cand comanda citita are valoarea “EXIT”, inseamna ca ziua s-a incheiat si putem inchide biblioteca. Mai ramane un singur lucru de facut, afisarea TOP_BOOKS si TOP_USERS.

TOP_BOOKS

Se afiseaza topul cartilor, in ordine descrescatoare dupa rating. Rating-ul se calculeaza ca suma note useri / numar de imprumuturi. Purchases reprezinta numarul total de imprumuturi finalizate cu succes (un imprumut este finalizat daca s-a oferit rating pentru carte). Rating-ul se va afisa cu eroare de 3 zecimale. Daca exista 2 carti cu acelasi rating, se va afisa mai intai cartea cu cele mai multe reviewuri. Daca exista 2 carti cu acelasi rating si acelasi numar de imprumuturi, se vor ordona crescator lexicografic dupa numele cartii. Format afisare:

Books ranking:

TOP_USERS

Se va afisa topul userilor, in ordine descrescatoare dupa punctaj. Doar userii nebanati vor fi afisati in top. Daca exista mai multi useri cu acelasi punctaj, se vor afisa in ordine lexicografica dupa nume. Format afisare:

Users ranking:

Exemplu

Input
ADD_BOOK "dex" 3
minge rotund
animal vietate
pufoaica haina
GET_DEF "dex" animal
ADD_DEF "dex" birou masa
GET_BOOK "dex"
ADD_DEF "dex" minge bila
ADD_DEF "dex" minge bila
RMV_DEF "dex" animal
GET_DEF "dex" animal
GET_BOOK "dex"
GET_BOOK "alabala"
ADD_USER ana 
ADD_USER ana
GET_DEF "dex" minge
GET_BOOK "dex"
ADD_USER rappyzaur
BORROW rappyzaur "dex" 10
RETURN rappyzaur "dex" 8 4
BORROW ana "dex" 10
GET_DEF "dex" birou
RETURN ana "dex" 17 5
BORROW ana "dex" 10
RETURN ana "dex" 7 2
EXIT
Output
vietate 
Name:dex Rating:0.000 Purchases:0
The definition is not in the book.
Name:dex Rating:0.000 Purchases:0
The book is not in the library.
User is already registered.
bila 
Name:dex Rating:0.000 Purchases:0
masa 
Books ranking:
1. Name:dex Rating:3.667 Purchases:3
Users ranking:
1. Name:rappyzaur Points:104
2. Name:ana Points:99

TL; DR

  • implementarea unui hashtable generic care trateaza coliziunile cu chaining.
  • hashtable-ul trebuie sa aiba implementata functionalitatea de resizing.
  • atat biblioteca, fiecare carte, cat si baza de date pentru useri trebuie implementate folosind hashtable-ul generic.
  • elementele unei carti sunt definitii; o definitie este o pereche (key, value).
  • elementele bibliotecii sunt cartile (adica un hashtable ce contine alte hashtable-uri).
  • comenzile trebuie rezolvate folosind functionalitatea hashtable-ului (de ex: pentru GET_DEF se foloseste functia get()).
  • testele de intrare vor contine comenzi de biblioteca si comenzi de user amestecate.
  • se citeste de la standard input (stdin) si se afiseaza la standard ouput (stdout).

Depunctari

Neimplementarea unui hasthable generic. Ar trebui sa puteti folosi aceeasi implementare atat pentru implementarea bibliotecii, a cartilor si a bazei de date pentru useri. -20p

Alocarea statica acolo unde se putea aloca dinamic (unde nu se cunoaste dimensiunea datelor se va aloca dinamic) -20p

Utilizarea variabilelor globale -20p

Eliberarea memoriei se va verifica folosind utilitarul Valgrind. O temă ce conține memory leaks va atrage după sine punctajul de 0p pe testul respectiv.

Alocarea initiala a unui hashtable prea mare (care nu respecta numarul de buckets precizat in enunt initial) si pentru care nu este nevoie de resize: -20p

Este obligatorie implementarea unui hashtable: nerespectarea acestei cerinte va aduce dupa sine punctajul 0 pe tema.

Nu copiați! Toate soluțiile vor fi verificate folosind o unealtă de detectare a plagiatului. În cazul detectării unui astfel de caz, atât plagiatorul cât și autorul original (nu contează cine e) vor primi punctaj 0 pe toate temele! De aceea, vă sfătuim să nu vă lăsați rezolvări ale temelor pe calculatoare partajate (la laborator etc), pe mail/liste de discuții/grupuri etc.

Checker

Checker: 2-checker-library.zip.

Temele vor fi trimise pe vmchecker. Atenție! Temele trebuie trimise în secțiunea Structuri de Date (CA).

Arhiva trebuie să conțină:

Punctaj

FAQ

Q: Se pot folosi flag-uri de optimizare?

A: Nu aveți voie să folosiți flag-uri de optimizare în Makefile (-O3, -O2, etc.).

Q: Tema 2 se poate face în C++?

A: Nu.

Q: Se pot folosi variabile globale?

A: Nu.

Q: Putem folosi scheletul de cod din laboratorul 4 (dictionar)?

A: DA :D. Puteti folosi atat scheletul pus la dispozitie de echipa de SDA cat si propria voastra rezolvare a laboratorului (nu aveti voie sa folositi rezolvarea colegului). De asemenea, nu aveti voie sa copiati rezolvarea hashtable-ului din scheletul altor laboratoare(7, 8, 9…).

Suport, întrebări și clarificări

Pentru întrebări sau nelămuriri legate de temă folosiți forumul temei.Orice întrebare e recomandat să conțină o descriere cât mai clară a eventualei probleme. Întrebări de forma: “Nu merge X. De ce?” fără o descriere mai amănunțită vor primi un răspuns mai greu.

ATENȚIE să nu postați imagini cu părți din soluția voastră pe forumul pus la dispoziție sau orice alt canal public de comunicație. Dacă veți face acest lucru, vă asumați răspunderea dacă veți primi copiat pe temă.