This shows you the differences between two versions of the page.
pa:laboratoare:laborator-00 [2021/03/02 21:42] darius.neatu [De ce PA?] |
pa:laboratoare:laborator-00 [2025/03/06 22:57] (current) darius.neatu [Exercitii] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Laborator 00: Intro to PA ====== | + | ====== Laborator 00: Intro to PA ====== |
- | Responsabili / autori: | + | |
- | * [[neatudarius@gmail.com|Darius-Florentin Neațu (2017-2021)]] | + | |
- | * [[radunichita99@gmail.com | Radu Nichita (2021)]] | + | |
- | * [[cristianolaru99@gmail.com | Cristian Olaru (2021)]] | + | |
- | * [[mirunaelena.banu@gmail.com | Miruna-Elena Banu (2021)]] | + | |
- | * [[maraioana9967@gmail.com | Mara-Ioana Nicolae (2021)]] | + | |
> PA = Proiectarea Algoritmilor | > PA = Proiectarea Algoritmilor | ||
===== De ce PA? ===== | ===== De ce PA? ===== | ||
Line 12: | Line 5: | ||
==== Ce este un algoritm? ==== | ==== Ce este un algoritm? ==== | ||
+ | |||
O succesiune determinată de pași care prelucrează datele de intrare pentru a obține datele de ieșire dorite. | O succesiune determinată de pași care prelucrează datele de intrare pentru a obține datele de ieșire dorite. | ||
- | ==== De ce ne trebuie algoritmi? ==== | + | |
- | Toate aplicațiile au un scop care poate fi atins folosind diverse metode: logica aplicației este împachetă sub diverși algoritmi specifici. | + | {{:pa::new_pa:algo.png?500 |}} |
==== De ce avem nevoie de algoritmi eficienți? ==== | ==== De ce avem nevoie de algoritmi eficienți? ==== | ||
Line 21: | Line 16: | ||
==== De ce PA? ==== | ==== De ce PA? ==== | ||
- | > "Pentru că scrie în orar.Ț (Radu Nichita, 2021) | + | > "Pentru că scrie în orar." (Radu Nichita, 2021) |
> "Pentru că m-a pus mama să termin ACS." (Cristian Olaru, 2021) | > "Pentru că m-a pus mama să termin ACS." (Cristian Olaru, 2021) | ||
- | > "Gigel be with you!" (Darius Neațu, 2017) | + | > "Pentru că nu există seriale pe Netflix mai lungi decât laburile lui Darius." (Miruna Banu, 2021) |
+ | > "Gigel be with you!" (Darius-Florentin Neațu, 2017) | ||
Line 33: | Line 29: | ||
===== Ce vom face? ===== | ===== Ce vom face? ===== | ||
- | Vom aprofunda elementele fundamentale necesare rezolvării fiecărei clase de probleme analizate, prezentând mai mulți algoritmi pentru fiecare problemă studiată și evidențiând pe cei optimi (eficienți). | + | Vom aprofunda elementele fundamentale necesare rezolvării fiecărei clase de probleme analizate, prezentând mai mulți algoritmi pentru fiecare problemă studiată și evidențiind pe cei optimi (eficienți). |
Pornind de la aceste elemente, vom accentua punctele de interes identificate, descoperind șabloane de rezolvare și modalități de construire a soluțiilor pentru o problemă. | Pornind de la aceste elemente, vom accentua punctele de interes identificate, descoperind șabloane de rezolvare și modalități de construire a soluțiilor pentru o problemă. | ||
Line 40: | Line 36: | ||
===== Limbaje de programare ===== | ===== Limbaje de programare ===== | ||
- | La PA este permisă folosirea limbajelor de programare: **C++** / **Java** / **C**. Din cauză că aproape orice algoritm studiat se bazează pe folosirea unor stucturi de date implementare, **NU** recomandăm folosirea limbajului C, întrucât bibliotecile standard nu au aceste structuri. | + | La PA este permisă folosirea limbajelor de programare: **C++** / **Java** / **C**. Din cauză că aproape orice algoritm studiat se bazează pe folosirea unor structuri de date implementate deja, **NU** recomandăm folosirea limbajului C, întrucât bibliotecile standard nu le conțin. |
===== De ce C++? ===== | ===== De ce C++? ===== | ||
Line 49: | Line 45: | ||
===== De ce nu alte limbaje? ===== | ===== De ce nu alte limbaje? ===== | ||
- | Considerăm că aceste 2 limbaje sunt 2 limbaje foarte folosite și că prin funcționalitățile oferite studentul se poate concentra efectiv pe implementarea algoritmilor și nu pe alte aspecte legate de limbaj. | + | Considerăm că acestea sunt 2 limbaje foarte folosite și că, prin funcționalitățile oferite, studentul se poate concentra efectiv pe implementarea algoritmilor și nu pe alte aspecte legate de limbaj. |
===== Coding Style ===== | ===== Coding Style ===== | ||
Line 60: | Line 56: | ||
+ | ===== Debugging ===== | ||
+ | Pe parcursul semestrului, vă poate fi util să știți cum se folosește un debugger pentru a găsi probleme într-un mod rapid. Vă recomandăm articolul [[https://ocw.cs.pub.ro/courses/programare/tutoriale/debugging | PC@Debugging]] pentru a vă reaminti de cum folosim GDB atât din CLI cât și prin intermediul unui IDE. | ||
====== Desfășurare laborator ===== | ====== Desfășurare laborator ===== | ||
- | În prima săptămână se va clone repo-ul de laborator conform instrucțiunilor de pe pagina [[https://ocw.cs.pub.ro/courses/pa/laboratoare/pa-lab |pa-lab]]. În fiecare săptămână se rulează comanda "git pull" pentru obținerea scheletului actualizat înainte de fiecare laborator. | + | În prima săptămână se va clona repo-ul de laborator conform instrucțiunilor de pe pagina [[https://ocw.cs.pub.ro/courses/pa/laboratoare/pa-lab |pa-lab]]. În fiecare săptămână se rulează comanda "git pull" pentru obținerea scheletului actualizat înainte de fiecare laborator. |
- | + | ||
- | În acest an, laboratorul valorează **0p**. Acesta se desfășoară sub formă de seminar: asistentul prezintă algoritmii studiați și rezolvă probleme împreună cu studenții. | + | |
Secțiunile de **Exerciții ** / **Bonus** / **Extra** reprezintă seturi de probleme grupate pe nivele de dificultate (de la ușor la greu). Recomandăm rezolvarea tuturor exercițiilor propuse, pentru înțelegerea algoritmilor studiați. | Secțiunile de **Exerciții ** / **Bonus** / **Extra** reprezintă seturi de probleme grupate pe nivele de dificultate (de la ușor la greu). Recomandăm rezolvarea tuturor exercițiilor propuse, pentru înțelegerea algoritmilor studiați. | ||
Line 70: | Line 66: | ||
===== Exercitii ===== | ===== Exercitii ===== | ||
- | În lab00 nu există exerciții propriu-zise. | + | |
Task-uri: | Task-uri: | ||
- | * Citiți README de pe pagina principala [[https://github.com/acs-pa/pa-lab | pa-lab]]. | + | * **Task00**: Citiți README de pe pagina principala [[https://github.com/acs-pa/pa-lab | pa-lab]]. Alegeți un limbaj de programare dintre C++ și Java și parcurgeți tutorialul aferent din [[https://github.com/acs-pa/pa-lab/tree/main/skel/lab00 | pa-lab::skel/lab00]]. |
- | * Fiecare trebuie să își aleagă un limbaj de programare și să facă tutorialul aferent din [[https://github.com/acs-pa/pa-lab/tree/main/skel/lab00 | pa-lab::skel/lab00]]. | + | * **Task01**: Se dă un vector cu n elemente și un număr k. Aflați al k-lea cel mai mare număr din vector. |
- | + | * **Restricții**: | |
+ | * $ 1 <= k <= n <= 10^5 $ | ||
+ | * Elementele vectorului au valori cuprinse între 0 și $ 10 ^ 9 $ | ||
+ | <note> | ||
+ | Ca să înțelegem cum ne dorim să procedăm la PA, următoarea problemă este rezolvată. Soluțiile pentru această problemă se pot încărca pe platforma [[https://leetcode.com/problems/kth-largest-element-in-an-array/description/ | Leetcode]]. | ||
+ | </note> | ||
+ | |||
+ | <spoiler Soluția 1> | ||
+ | Putem sorta vectorul crescător și să întoarcem al k-lea element de la finalul vectorului. Complexitate este de $ O(n log n) $. | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 1 implementată în C++> | ||
+ | <code cpp> | ||
+ | class Solution { | ||
+ | public: | ||
+ | int findKthLargest(vector<int>& nums, int k) { | ||
+ | std::sort(nums.begin(), nums.end()); | ||
+ | return nums[nums.size() - k]; | ||
+ | } | ||
+ | }; | ||
+ | </code> | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 1 implementată în Java> | ||
+ | <code java> | ||
+ | class Solution { | ||
+ | public int findKthLargest(int[] nums, int k) { | ||
+ | Arrays.sort(nums); | ||
+ | return nums[nums.length - k]; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 2> | ||
+ | Pentru soluția precedentă, nu ne-am folosit de faptul că $ k < n $, deci s-ar putea obține ceva mai eficient. Trebuie să parcugem măcar o dată vectorul, deci mai puțin de $ O(n)$ nu putem obține. Fix n pași nu putem face, trebuie să îl folosim pe k. Deoarece ne trebuie al k-lea cel mai mare element, intuitiv ar trebui să ținem minte într-o structură de date cele mai mari k elemente din vector. | ||
+ | |||
+ | Ce structură alegem? Dorim să putem insera în ea și să ne zică maximul. Am fi tentați să folosim un max heap. | ||
+ | |||
+ | Când am adăuga un nou element, am dori să îl ștergem pe cel mai mic din structura de date. Prin urmare, am putea să folosim un min heap, în care ne propunem ca la orice moment stocăm cele mai mari k elemente din vector, parcurse până acum. | ||
+ | |||
+ | Astfel: | ||
+ | |||
+ | 1. Se adaugă inițial primele k elemente în heap. | ||
+ | |||
+ | 2. Pentru fiecare din elementele următoarele, dacă acesta este mai mare decât minimul din heap, se șterge minimul și se adaugă elementul curent. Mereu în heap avem k elemente la final de pas în această etapă. | ||
+ | |||
+ | 3. Răspunsul este minimul din heap la finalul parcurgerii. | ||
+ | |||
+ | Complexitate este de $ O(n log k) $, care este mai bună. Implementați și testați pe Leetcode! | ||
+ | |||
+ | </spoiler> | ||
+ | |||
+ | <spoiler Soluția 3> | ||
+ | Hint: Soluția 2 nu este optimă! Se poate și $O(n)$, dar considerăm că este înafara scopului laboratorului 0. | ||
+ | </spoiler> | ||
+ | |||
+ | * **Task02**: Discutați problema [[https://leetcode.com/problems/sliding-window-maximum/| Sliding Window Maximum]] și problema [[https://leetcode.com/problems/longest-substring-without-repeating-characters| Longest Substring without repeating characters]]. Implementați și testați cel puțin o problemă. | ||
+ | |||
+ | * **Task03**: Rezolvați problema [[https://leetcode.com/problems/min-stack/description/| Min Stack]]. |