This shows you the differences between two versions of the page.
|
poo:laboratoare:07 [2025/11/17 21:28] george.tudor1906 [Problema 5] |
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 ==== | ||
| - | 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ă). | + | 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 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ă. | ||
| Line 76: | Line 76: | ||
| ''Collections.sort'' sortează o colectie după un criteriu definit. | ''Collections.sort'' sortează o colectie după un criteriu definit. | ||
| </note> | </note> | ||
| + | |||
| + | |||
| + | |||
| + | ==== Problema 6 ==== | ||
| + | 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. | ||
| + | |||
| + | 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> | ||
| + | Pentru fișierul de intrare din arhivă (capacitate 3, loadfactor 0.75), output-ul trebuie să fie: | ||
| + | |||
| + | <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> | ||
| + | |||