Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo:laboratoare:07 [2025/11/17 21:13]
george.tudor1906 [Problema 2]
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 31: Line 31:
  
 ==== Problema 3 ==== ==== Problema 3 ====
-Să se definească o clasă ​**//SListSet//** pentru ​o mulțime ordonată de obiecte, care extinde clasa **//LinkedList//** si implementează ​interfața **//​SortedSet//​**. Clasa va conține un obiect ​de tip **//Comparator//** și metodele:+Se cere realizarea unei clase **SListSet** ​care modelează ​o mulțime ordonată de obiecte ​peste o listă înlănțuită. Clasa **extinde ​LinkedList** ​și **implementează ​SortedSet** (fără generics; elementele sunt de tip Object). Ordinea elementelor este dată de un Comparator furnizat la creare sau, dacă acesta este null, de ordinea naturală ​elementelor. Două elemente sunt considerate ​**duplicate** atunci când comparația lor dă zero (compare(a, b) == 0), iar mulțimea nu trebuie să conțină două astfel ​de elemente. ​**Nu se acceptă valori null**. Dacă parametrul Comparator este null, toate elementele introduse trebuie să fie //Comparable// - în caz contrar se aruncă o excepție clară (de exemplu //​ClassCastException//​ / //​IllegalArgumentException//​).
  
 <note tip> <note tip>
 <code java> <code java>
-Comparator comparator () ; //​comparator folosit (null pentru ​ comparatia ​naturala)  +Comparator comparator();​ //​comparator folosit (null pentru comparatia ​naturală)  
-boolean add(Object o); //adauga ​un elemnt ​in multime daca nu exista ​deja si sorteaza multimea +boolean add(Object o); //adaugă ​un elemnt ​în mulțime dacă nu există ​deja și sortează mulțimea 
-Object first(); //primul obiect din multime +Object first(); //primul obiect din mulțime 
-Object last(); // ultimul obiect din multime +Object last(); // ultimul obiect din mulțime 
-SortedSet subSet(Object from, Object to); // o submultime ordonata +SortedSet subSet(Object from, Object to); // copie ordonată a intervalului [from, to) 
-SortedSet headSet(Object to); // o submultime cu primele ​ obiecte +SortedSet headSet(Object to); // copie ordonată a intervalului (primul_element,​ to) 
-SortedSet tailSet(Object from); //o submultime cu ultimele obiecte+SortedSet tailSet(Object from); copie ordonată a intervalului [from, ultimul_element) 
 +SListSet reversed(); // întoarce ​copie a mulțimii ordonată descrescător,​ construită pe baza comparatorului curent (dacă există) sau a ordinii naturale; populați exclusiv din elementele setului curent, fără recitirea fișierului și fără sortări/​inversări externe.
 </​code>​ </​code>​
 </​note>​ </​note>​
-Se vor defini cel puțin doi constructori:​ fără argumente (sortare conform ordinii naturale) și cu un argument de tip **//​Comparator//​**. 
-Să se folosească un obiect de tip **//​SListSet//​** pentru afișarea cuvintelor distincte dintr-un text citit dintr-un fișier text (//​test01.txt//​),​ în ordine crescătoare sau descrescătoare (în locul clasei **//​TreeSet//​** din problema 1).  
  
-==== Problema 4 ==== +Se vor defini ​**doi constructori**
-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//​**.+  * **SListSet()** - comparator == nulldeci ordine naturală (necesită elemente Comparable);​ 
 +  ​* **SListSet(Comparator cmp**) - ordine definită de cmp.
  
-Pentru afisare se va folosi ​un Iterator pe multimea intrarilor din dictionar. La afișarefiecare 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șla sfârșit numărul de apariții al acestuia.+Programul ​va folosi ​SListSet pentru a afișa cuvintele distincte dintr-un fișier text (//​test1.txt//​)în ordine crescătoare și în ordine descrescătoare, ​fără ​apela sortări din afara colecției. Delimitarea cuvintelor este identică cu Problema 1.
  
-Se poate folosi ​ca fisier ​de intrare tot fisierul test01.in din arhiva!+==== 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ă).
    
-<note tip> +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ă. 
-Map - //**entrySet()**//+ 
 +Fișierul de intrare recomandat: test4.txt din arhivă.
  
-Set - //​**iterator()**//​ 
-</​note>​ 
  
  
 ==== Problema 5 ==== ==== 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. +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 folosi succesiv clasele ​**//HashMap//** și **//TreeMap//**+ 
-Afișarea ​se va face atât în ordinea ​alfabetică a numelor ​cât și în ordinea dimensiunii fișierelor ​(două afișări).+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
  
 <note tip> <note tip>
-''​entrySet''​ din ''​Map''​ transformă colecția în ''​Set''​ de intrari;+''​entrySet''​ din ''​Map''​ transformă colecția în ''​Set''​ de intrări;
  
 ''​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>​
 +
  
poo/laboratoare/07.1763406821.txt.gz · Last modified: 2025/11/17 21:13 by george.tudor1906
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0