Differences

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

Link to this comparison view

poo-is-ab:laboratoare:11 [2025/12/07 18:29]
razvan.cristea0106 [Funcții lambda și algoritmi]
poo-is-ab:laboratoare:11 [2025/12/08 19:14] (current)
razvan.cristea0106 [Funcții lambda și algoritmi]
Line 59: Line 59:
 ==== Clasa string ==== ==== Clasa string ====
  
-Așa cum am menționat mai sus clasa **string** este o clasă specială în C++ pentru lucrul cu **șiruri de caractere**. Această clasă a fost introdusă pentru a simplifca masiv lucrul cu datele de tip **''​char*''​**. Un **string** își actualizează dimensiunea dinamic în funcție de ce operații suferă iar la final, când durata de viață a acestuia se încheie, este chemat automat destructorul care dezalocă ​automat ​memoria.+Așa cum am menționat mai sus clasa **string** este o clasă specială în C++ pentru lucrul cu **șiruri de caractere**. Această clasă a fost introdusă pentru a simplifca masiv lucrul cu datele de tip **''​char*''​**. Un **string** își actualizează dimensiunea dinamic în funcție de ce operații suferă iar la final, când durata de viață a acestuia se încheie, este chemat automat destructorul care dezalocă memoria ​ocupată de acesta.
  
-În continuare vom prezenta un tabel unde sunt descrise principalele metode și operatori ​care există în clasa **string**.+În continuare vom prezenta un tabel unde sunt descrise principalele metode și operatori ​din clasa **string**.
  
 ^   ​Denumire metodă / Operator ​  ​^ ​  ​Descriere ​  ^ ^   ​Denumire metodă / Operator ​  ​^ ​  ​Descriere ​  ^
Line 139: Line 139:
 <note warning>​Dacă vom citi un **string** cu **operatorul %%>>​%%** trebuie menționat faptul că acesta va fi citit până la apariția primului **spațiu**,​ similar cu ceea ce se întâmpla în cazul **șirurilor de caractere** din limbajul **C** atunci când erau citite cu funcția **scanf**.</​note>​ <note warning>​Dacă vom citi un **string** cu **operatorul %%>>​%%** trebuie menționat faptul că acesta va fi citit până la apariția primului **spațiu**,​ similar cu ceea ce se întâmpla în cazul **șirurilor de caractere** din limbajul **C** atunci când erau citite cu funcția **scanf**.</​note>​
  
-<note tip>​Pentru a citi de la tastatură sau din fișier un **string** până la apariția caracterului **''\n''** ne putem folosi de funcția **getline**.+<note tip>​Pentru a citi de la tastatură sau din fișier un **string** până la apariția caracterului **'​\n'​** ne putem folosi de funcția **getline**.
 </​note>​ </​note>​
  
Line 251: Line 251:
 ==== Clasa vector ==== ==== Clasa vector ====
  
-Pentru clasa **vector** propunem următorul tabel ca și referință:+Pentru clasa **vector** propunem următorul tabel ca și referință.
  
 ^     ​Denumire metodă/​Operator ​    ​^ ​    ​Descriere ​    ^ ^     ​Denumire metodă/​Operator ​    ​^ ​    ​Descriere ​    ^
Line 789: Line 789:
 </​code>​ </​code>​
  
-<note tip>​Pentru a putea modifica **valorile copiilo**r în interiorul **expresiei lambda** trebuie să o marcăm ca fiind **mutabilă**. În acest sens trebuie să utilizăm cuvântul cheie ''​**mutable**'' ​care ne dă posibilitatea să **modificăm variabilele capturate prin valoare** în interiorul unei **funcții anonime**, însă modificările **nu** afectează **variabilele originale** din exterior, deoarece **funcția lambda** lucrează cu **copii** ale acestora.</​note>​+<note tip>​Pentru a putea modifica **valorile copiilo**r în interiorul **expresiei lambda** trebuie să o marcăm ca fiind **mutabilă**. În acest sens trebuie să utilizăm cuvântul cheie **mutable** care ne dă posibilitatea să **modificăm variabilele capturate prin valoare** în interiorul unei **funcții anonime**, însă modificările **nu** afectează **variabilele originale** din exterior, deoarece **funcția lambda** lucrează cu **copii** ale acestora.</​note>​
  
 Așadar vom rescrie exemplul de mai sus în care vom avea posibilitatea de această dată să modificăm valoarea copiei lui ''​**a**''​ în interiorul funcției lambda. Așadar vom rescrie exemplul de mai sus în care vom avea posibilitatea de această dată să modificăm valoarea copiei lui ''​**a**''​ în interiorul funcției lambda.
Line 873: Line 873:
 === Algoritmi === === Algoritmi ===
  
-Pentru a folosi algoritmii din **STL** vom include fișierul antet **''​algorithm''​**. ​Acest fișier ​cuprinde algoritmi de **sortare**,​ **căutare**,​ **numărare** și mulți alții pe care **nu** mai trebuie să îi rescriem noi de la **zero**. Tot ceea ce avem de făcut este să înțelegem cum și când să îi folosim în funcție de context.+Pentru a folosi algoritmii din **STL** vom include fișierul antet **''​algorithm''​**. ​Această librărie ​cuprinde algoritmi de **sortare**,​ **căutare**,​ **numărare** și mulți alții pe care **nu** mai trebuie să îi rescriem noi de la **zero**. Tot ceea ce avem de făcut este să înțelegem cum și când să îi folosim în funcție de context.
  
 == Sortarea elementelor unui vector de numere întregi ==  == Sortarea elementelor unui vector de numere întregi == 
  
 +Pentru a putea sorta diferite containere cum ar fi vectorii se folosește cel mai adesea funcția ''​**sort**''​ care este un algoritm de sortare cu o complexitate de O(NlogN). Acest algoritm este de fapt un mix între QuickSort și HeapSort, fiind foarte rapid chiar și pentru un număr foarte mare de elemente într-o colecție.
  
 +În mod implicit atunci când folosim această funcție generică sortarea va fi crescătoare.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <​vector>​
 +#include <​algorithm>​
 +
 +int main()
 +{
 +    std::​vector<​int>​ numere = { 42, -7, 15, 0, 99, 23, -12, 8, 54, 3 };
 +
 +    std::cout << "​Vectorul initial: ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    std::​sort(numere.begin(),​ numere.end());​ // sortare crescatoare
 +
 +    std::cout << "​Vectorul sortat: ​ ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    return 0;
 +}
 +</​code>​
 +
 +Dacă am dori să avem un vector sortat descrescător acest lucru ar fi echivalent cu a construi un criteriu custom de sortare pentru a putea face funcția de sortare să înțeleagă faptul că ne dorim să vedem elementele ordonate de la cel mai mare la cel mai mic. Avem două variante prin care putem să facem acest lucru și anume: folosind o funcție care joacă rol de comparator și în care scriem criteriul de sortare sau folosind o expresie lambda în care punem logica de sortare.
 +
 +Pentru a sorta descrescător vectorul folosind un comparator putem proceda în felul următor.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <​vector>​
 +#include <​algorithm>​
 +
 +bool ordoneazaDescrescator(const int& x, const int& y)
 +{
 +    return x > y;
 +}
 +
 +int main()
 +{
 +    std::​vector<​int>​ numere = { 42, -7, 15, 0, 99, 23, -12, 8, 54, 3 };
 +
 +    std::cout << "​Vectorul initial: ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    std::​sort(numere.begin(),​ numere.end(),​ ordoneazaDescrescator);​ // se trimite un function pointer
 +
 +    std::cout << "​Vectorul sortat: ​ ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    return 0;
 +}
 +</​code>​
 +
 +Varianta mai elegantă este să folosim o funcție lambda care aplică aceeași logică de comparație ca și funcția responsabilă de ordonarea descrescătoare de la exemplul anterior.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <​vector>​
 +#include <​algorithm>​
 +
 +int main()
 +{
 +    std::​vector<​int>​ numere = { 42, -7, 15, 0, 99, 23, -12, 8, 54, 3 };
 +
 +    std::cout << "​Vectorul initial: ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    std::​sort(numere.begin(),​ numere.end(),​ [](const int& x, const int& y)
 +        {
 +            return x > y;
 +        });
 +
 +    std::cout << "​Vectorul sortat: ​ ";
 +
 +    for (const int& numar : numere)
 +    {
 +        std::cout << numar << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    return 0;
 +}
 +</​code>​
 +
 +== Căutarea binară a unui element într-o listă ==
 +
 +Pentru a aplica căutarea binară într-o listă mai întâi trebuie să ne sortăm acea listă. Mai mult lista nu are iteratori de tip random acces, deci va trebui să o convertim într-un vector pentru a putea aplica funcția generică de ''​**binary_search**''​.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <​list>​
 +#include <​vector>​
 +#include <​algorithm>​
 +
 +int main()
 +{
 +    std::​list<​float>​ valori = { 3.5f, 1.2f, 9.8f, 7.1f, 4.0f, 2.2f };
 +
 +    valori.sort();​
 +
 +    std::cout << "Lista sortata: ";
 +
 +    for (float x : valori)
 +    {
 +        std::cout << x << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    std::​vector<​float>​ vec(valori.begin(),​ valori.end());​
 +
 +    float elementCautat = 4.0f;
 +    bool gasit = std::​binary_search(vec.begin(),​ vec.end(), elementCautat);​
 +
 +    if (gasit == true)
 +    {
 +        std::cout << "​Elementul " << elementCautat << " a fost gasit!\n";​
 +    }
 +    else
 +    {
 +        std::cout << "​Elementul " << elementCautat << " NU exista in lista.\n";​
 +    }
 +
 +    return 0;
 +}
 +</​code>​
 +
 +Dacă intenționăm să avem și acces la poziția și valoarea elementului căutat atunci vom folosi funcția generică ''​**lower_bound**''​ care face căutare binară de asemenea, dar va returna și un iterator spre elementul găsit în caz de succes.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <​list>​
 +#include <​vector>​
 +#include <​algorithm>​
 +
 +int main()
 +{
 +    std::​list<​float>​ valori = { 3.5f, 1.2f, 9.8f, 7.1f, 4.0f, 2.2f };
 +
 +    valori.sort();​
 +
 +    std::cout << "Lista sortata: ";
 +
 +    for (float x : valori)
 +    {
 +        std::cout << x << " ";
 +    }
 +
 +    std::cout << "​\n";​
 +
 +    std::​vector<​float>​ vec(valori.begin(),​ valori.end());​
 +
 +    float elementCautat = 4.0f;
 +    auto it = std::​lower_bound(vec.begin(),​ vec.end(), elementCautat);​
 +
 +    if (it != vec.end() && *it == elementCautat)
 +    {
 +        std::cout << "​Elementul gasit: " << *it << "​\n";​
 +        std::cout << "​Pozitia in vector: " << (it - vec.begin()) << "​\n";​
 +    }
 +    else
 +    {
 +        std::cout << "​Elementul " << elementCautat << " NU exista in lista.\n";​
 +    }
 +
 +    return 0;
 +}
 +</​code>​
 +
 +== Cuvântul cu lungimea cea mai mare dintr-un set de cuvinte unice ==
 +
 +Pentru a putea găsi cuvântul cel mai lung în orice structură de date, nu contează că vorbim aici despre set, map, sau vector putem utiliza funcția generică ''​**max_element**''​ care întoarce un iterator spre elementul găsit ca fiind cel care respectă condiția de maxim.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <set>
 +#include <​algorithm>​
 +
 +int main()
 +{
 +    std::​set<​std::​string>​ cuvinte
 +    {
 +        "​programare",​
 +        "​C++",​
 +        "​C#",​
 +        "​laborator",​
 +        "​iterator",​
 +        "​pointer",​
 +        "​metoda",​
 +        "​constructor",​
 +        "​algoritm",​
 +        "​calculator"​
 +    };
 +
 +    auto it = std::​max_element(cuvinte.begin(),​ cuvinte.end(),​ [](const std::​string&​ s1, const std::​string&​ s2)
 +        {
 +            return s1.size() < s2.size();
 +        }
 +    );
 +
 +    if (it != cuvinte.end())
 +    {
 +        std::cout << "​Cuvantul cu lungimea cea mai mare din arbore este: "
 +            << *it << " (lungime = " << it->​size() << ") caractere\n";​
 +    }
 +
 +    return 0;
 +}
 +</​code>​
  
 == Numărul de apariții al unui element într-un vector == == Numărul de apariții al unui element într-un vector ==
Line 889: Line 1130:
 int main() int main()
 { {
-    std::​vector<​int>​ numere+    std::​vector<​int>​ numere ​= { 1005218152268182718 };
- +
-    numere.push_back(100); +
-    numere.push_back(5); +
-    numere.push_back(2); +
-    numere.push_back(18); +
-    numere.push_back(15); +
-    numere.push_back(22); +
-    numere.push_back(6); +
-    numere.push_back(8); +
-    numere.push_back(18); +
-    numere.push_back(27); +
-    numere.push_back(18);+
  
     int target = 18; // valoarea careia vrem sa ii aflam numarul de aparitii din vector     int target = 18; // valoarea careia vrem sa ii aflam numarul de aparitii din vector
Line 912: Line 1141:
 </​code>​ </​code>​
  
-== ==+=== ===
  
 <note tip>​Pentru mai mulți algoritmi puși la dispoziție de această librărie recomandăm citirea documentației oficiale care se află chiar [[https://​en.cppreference.com/​w/​cpp/​algorithm|aici]].</​note>​ <note tip>​Pentru mai mulți algoritmi puși la dispoziție de această librărie recomandăm citirea documentației oficiale care se află chiar [[https://​en.cppreference.com/​w/​cpp/​algorithm|aici]].</​note>​
poo-is-ab/laboratoare/11.1765124940.txt.gz · Last modified: 2025/12/07 18:29 by razvan.cristea0106
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