This shows you the differences between two versions of the page.
|
poo:laboratoare:07 [2025/11/17 21:21] george.tudor1906 [Problema 3] |
poo:laboratoare:07 [2025/11/20 08:01] (current) george.tudor1906 [Problema 4] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ===== Laboratorul 07. ===== | ===== Laboratorul 07. ===== | ||
| - | Arhiva laborator: {{:poo:laboratoare:arhiva7.zip| Arhiva}} | + | Arhiva laborator: {{:poo:laboratoare:arhiva_lab7.zip| Arhiva}} |
| Line 35: | Line 35: | ||
| <note tip> | <note tip> | ||
| <code java> | <code java> | ||
| - | Comparator comparator () ; //comparator folosit (null pentru comparatia naturală) | + | Comparator comparator(); //comparator folosit (null pentru comparatia naturală) |
| boolean add(Object o); //adaugă un elemnt în mulțime dacă nu există deja și sortează mulțimea | boolean add(Object o); //adaugă un elemnt în mulțime dacă nu există deja și sortează mulțimea | ||
| Object first(); //primul obiect din mulțime | Object first(); //primul obiect din mulțime | ||
| Line 53: | Line 53: | ||
| ==== Problema 4 ==== | ==== Problema 4 ==== | ||
| - | Program pentru afișarea numerelor liniilor dintr-un fișier text în care apare fiecare cuvânt distinct. Se va folosi un dicționar cu liste de valori asociate fiecărei chei. Dicționarul va fi de tip **//TreeMap//**, iar listele vor fi de tip **//LinkedList//**. | + | Realizați un program care citește un fișier text și afișează, pentru **fiecare cuvânt distinct**, numerele liniilor în care apare și, la final, numărul total de apariții ale acelui cuvânt. Se va utiliza un **dicționar ordonat alfabetic** după cuvânt, implementat ca **TreeMap<String, LinkedList<Integer> >**: cheia este cuvântul, iar valoarea este lista numerelor de linie pentru **fiecare apariție** (dacă același cuvânt apare de mai multe ori pe aceeași linie, numărul liniei se repetă în listă). |
| + | |||
| + | Pentru afișare se va itera cu un **Iterator** peste mulțimea intrărilor dicționarului obținută prin **Map.entrySet()**. Pentru fiecare intrare, se va tipări **cuvântul** pe o linie separată urmat, pe liniile următoare, de lista numerelor de linie (în ordinea colectării), iar la final "Total: N", unde N este dimensiunea listei aferente cuvântului. Fiecare cuvânt începe pe o linie nouă. | ||
| - | Pentru afisare se va folosi un Iterator pe multimea intrarilor din dictionar. La afișare, fiecare cuvânt va începe pe o linie nouă și va fi urmat, pe liniile următoare, de lista numerelor liniilor în care apare. Pentru fiecare cuvânt în parte se va afișa la sfârșit numărul de apariții al acestuia. | + | Fișierul de intrare recomandat: test4.txt din arhivă. |
| + | |||
| + | |||
| + | |||
| + | ==== Problema 5 ==== | ||
| + | Realizați un program care, pentru un director dat, construiește și afișează un dicționar cu **numele fișierelor** (cheia) și **dimensiunea lor** exprimată în kiloocteți (KiB) ca număr întreg (valoarea). Dicționarul se va construi **inițial** folosind HashMap<String, Integer>, apoi se va **reorganiza** într-un TreeMap<String, Integer> pentru afișarea alfabetică a numelor. Dimensiunea în KiB se calculează prin rotunjire în sus: KiB = (bytes + 1023) / 1024. | ||
| + | |||
| + | Programul va produce două afișări separate: | ||
| + | * **în ordine alfabetică după nume** - folosind TreeMap (ordonarea naturală a cheilor String). | ||
| + | * î**n ordine descrescătoare după dimensiune** - obținută prin transformarea mulțimii de intrări (entrySet()) într-o listă și sortarea ei cu Collections.sort / List.sort după dimensiune (descrescător). | ||
| + | |||
| + | |||
| + | Pentru fiecare afișare, fiecare linie va conține numele fișierului urmat de dimensiunea în KiB (de ex.: readme.txt - 5 KiB). Programul primește calea directorului ca argument; dacă lipsește, se poate folosi directorul curent. | ||
| - | Se poate folosi ca fisier de intrare tot fisierul test01.in din arhiva! | ||
| - | |||
| <note tip> | <note tip> | ||
| - | Map - //**entrySet()**// | + | ''entrySet'' din ''Map'' transformă colecția în ''Set'' de intrări; |
| - | Set - //**iterator()**// | + | ''Collections.sort'' sortează o colectie după un criteriu definit. |
| </note> | </note> | ||
| - | ==== Problema 5 ==== | + | |
| - | Program pentru crearea și afișarea unui dicționar cu numele fișierelor dintr-un director împreună cu dimensiunea lor exprimată în kiloocteți (ca număr întreg). Numele reprezintă cheia, iar dimensiunea este valoarea asociată cheii. | + | ==== Problema 6 ==== |
| - | Programul va folosi succesiv clasele **//HashMap//** și **//TreeMap//**. | + | Se cere realizarea unui program care implementează o **memorie cache cu capacitate fixă** și politică **LRU**: la depășirea capacității este eliminată intrarea folosită cel mai demult. "Folosire" înseamnă acces prin get (citire) sau put (inserare/actualizare). Implementarea se va baza exclusiv pe colecțiile standard Java. |
| - | Afișarea se va face atât în ordinea alfabetică a numelor cât și în ordinea dimensiunii fișierelor (două afișări). | + | |
| + | Cache-ul va fi realizat ca o clasă **LruCache** care **extinde** **LinkedHashMap** în regim de //access-order// (ordonare după ultimul acces), prin apelarea constructorului potrivit și suprascrierea metodei removeEldestEntry. Eliminarea celui mai vechi element din punct de vedere al accesului trebuie să se producă automat imediat după o operație care ar face cache-ul să depășească capacitatea. | ||
| + | |||
| + | Programul citește dintr-un fișier text o **succesiune** de operații asupra cache-ului și afișează atât **rezultatul operațiilor de tip GET**, cât și **starea finală a cache-ului în ordinea LRU**. Fișierul conține câte o instrucțiune pe linie, în formatul: | ||
| + | * //PUT <cheie><valoare>// - inserează sau actualizează intrarea; la actualizare intrarea devine "cea mai recent folosită". | ||
| + | * //GET <cheie>// - afișează valoarea asociată sau NULL dacă lipsește; la acces reușit, intrarea devine "cea mai recent folosită". | ||
| + | * Liniile goale sau cele care încep cu # sunt ignorate. Cheile și valorile se tratează ca șiruri simple (fără spații în interior). | ||
| + | |||
| + | **Ordinea de afișare a cache-ului**: se iterează în ordinea //access-order// a LinkedHashMap (de la cea mai veche la cea mai recentă). Se tipărește câte o intrare pe linie, în forma //<cheie>=<valoare>//. Între rezultatele GET și listarea finală se afișează o linie separatoare //---//. | ||
| + | |||
| + | Programul primește două argumente din linia de comandă: **capacitatea** cache-ului (număr întreg strict pozitiv) și **calea fișierului de operații**. | ||
| + | |||
| + | Programul va conține următoarele elemente **obligatorii**: | ||
| + | * <code java> | ||
| + | // O clasă fără generics: | ||
| + | |||
| + | class LruCache extends LinkedHashMap { | ||
| + | public LruCache(int capacity) { ...} // seteaza access-order = true | ||
| + | protected boolean removeEldestEntry(Map.Entry eldest) { ... } // eliminare cand size() > capacity | ||
| + | } | ||
| + | |||
| + | // Cheile null sunt interzise (verificate în put). | ||
| + | |||
| + | // Capacity se memorează în obiect și este strict pozitiv. | ||
| + | </code> | ||
| + | |||
| + | |||
| + | * <code java> | ||
| + | // O metodă statică ce execută operațiile citite din fișier și returnează cache-ul: | ||
| + | |||
| + | public static LruCache runOps(String opsFile, int capacity) throws IOException {...} | ||
| + | |||
| + | // Citește fișierul, interpretează liniile în ordine, pentru GET afișează imediat rezultatul (valoare sau NULL). | ||
| + | |||
| + | // Ignoră liniile invalide (nu oprește programul). | ||
| + | </code> | ||
| + | |||
| + | |||
| + | * <code java> | ||
| + | // O metodă statică pentru afișarea stării curente a cache-ului în ordinea LRU: | ||
| + | |||
| + | public static void printCache(LruCache cache){...} | ||
| + | |||
| + | // Parcurge intrările cache.entrySet() și tipărește <cheie>=<valoare> pe linie. | ||
| + | </code> | ||
| + | |||
| + | |||
| + | În metoda main se validează argumentele, se apelează runOps(...), se afișează linia ---, apoi printCache(...). | ||
| <note tip> | <note tip> | ||
| - | ''entrySet'' din ''Map'' transformă colecția în ''Set'' de intrari; | + | Pentru fișierul de intrare din arhivă (capacitate 3, loadfactor 0.75), output-ul trebuie să fie: |
| - | ''Collections.sort'' sortează o colectie după un criteriu definit. | + | <code java> |
| + | 1 | ||
| + | NULL | ||
| + | 3 | ||
| + | NULL | ||
| + | 30 | ||
| + | NULL | ||
| + | 5 | ||
| + | 6 | ||
| + | --- | ||
| + | C=30 | ||
| + | E=5 | ||
| + | F=6 | ||
| + | </code> | ||
| + | |||
| + | Explicația se găsește la fiecare pas în fișierul de intrare. | ||
| </note> | </note> | ||
| + | |||