Container Classes/ro: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(Images)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=Containere și iteratori=
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}


==Generalități==
[[Category:Learning]]


Qt are clase pentru a înlocui clasele C + + <span class="caps">STL</span>. Containerele Qt sunt clase șablon și pot conține orice alte clase mutabile. Aceste clase container au fost concepute pentru a fi mai compacte, mai sigure și mai ușor de folosit decât containerele <span class="caps">STL</span>. Ele sunt [http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html partajate implicit] ''[doc.qt.nokia.com]'' și pot fi apelate din mai multe threaduri. Există o largă gamă de containere, incluzând aici liste, stive, cozi, vectori asociativi și liste hash. Aceste clase conțin iteratori compatibili cu <span class="caps">STL</span>, cât și iteratori inspirați din Java. Iteratorii sunt obiecte care sunt utilizate pentru a se deplasa în cadrul unui container și pentru a obține acces la datele păstrate în el. Qt mai oferă de asemenea și cuvântul cheie '''foreach''' care face foarte facilă iterarea prin elementele conținute de o clasă container. Qt oferă următoarele '''containere secvenţiale''':
= Containere și iteratori =


# [http://doc.qt.nokia.com/4.7-snapshot/qlist.html QList] ''[doc.qt.nokia.com]''
== Generalități ==
# [http://doc.qt.nokia.com/4.7-snapshot/qlinkedlist.html QLinkedList] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qvector.html QVector] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qstack.html QStack] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qqueue.html QQueue] ''[doc.qt.nokia.com]''


Pentru majoritatea aplicaţiilor '''QList''' este cel mai recomdat. Dacă aveți nevoide de o listă înlănțuită utlizați '''QLinkedList'''; dacă doriți ca elementele să ocupe locuri consecutive în memorie se utilizează '''QVector'''. '''QStack''' şi '''QQueue''' oferă containeri cu semantică ''<span class="caps">LIFO</span>'' și ''<span class="caps">FIFO</span>''.
Qt are clase pentru a înlocui clasele C + + STL. Containerele Qt sunt clase șablon și pot conține orice alte clase mutabile. Aceste clase container au fost concepute pentru a fi mai compacte, mai sigure și mai ușor de folosit decât containerele STL. Ele sunt [http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html partajate implicit] și pot fi apelate din mai multe threaduri. Există o largă gamă de containere, incluzând aici liste, stive, cozi, vectori asociativi și liste hash. Aceste clase conțin iteratori compatibili cu STL, cât și iteratori inspirați din Java. Iteratorii sunt obiecte care sunt utilizate pentru a se deplasa în cadrul unui container și pentru a obține acces la datele păstrate în el. Qt mai oferă de asemenea și cuvântul cheie '''foreach''' care face foarte facilă iterarea prin elementele conținute de o clasă container. Qt oferă următoarele '''containere secvenţiale''':
 
# [http://doc.qt.nokia.com/4.7-snapshot/qlist.html QList]
# [http://doc.qt.nokia.com/4.7-snapshot/qlinkedlist.html QLinkedList]
# [http://doc.qt.nokia.com/4.7-snapshot/qvector.html QVector]
# [http://doc.qt.nokia.com/4.7-snapshot/qstack.html QStack]
# [http://doc.qt.nokia.com/4.7-snapshot/qqueue.html QQueue]
 
Pentru majoritatea aplicaţiilor '''QList''' este cel mai recomdat. Dacă aveți nevoide de o listă înlănțuită utlizați '''QLinkedList'''; dacă doriți ca elementele să ocupe locuri consecutive în memorie se utilizează '''QVector'''. '''QStack''' şi '''QQueue''' oferă containeri cu semantică ''LIFO'' și ''FIFO''.


Qt oferă de asemenea și '''containere asociative''':
Qt oferă de asemenea și '''containere asociative''':


# [http://doc.qt.nokia.com/4.7-snapshot/qmap.html QMap] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qmap.html QMap]
# [http://doc.qt.nokia.com/4.7-snapshot/qmultimap.html QMultiMap] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qmultimap.html QMultiMap]
# [http://doc.qt.nokia.com/4.7-snapshot/qhash.html QHash] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qhash.html QHash]
# [http://doc.qt.nokia.com/4.7-snapshot/qmultimap.html QMultiHash] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qmultimap.html QMultiHash]
# [http://doc.qt.nokia.com/4.7-snapshot/qset.html QSet] ''[doc.qt.nokia.com]''
# [http://doc.qt.nokia.com/4.7-snapshot/qset.html QSet]


Containerele ''multi'' furnizează suport pentru valori asociate mai multor chei. Containerele ''hash'' furnizează căutări mai rapide utilizând funcții ''hash'' în loc de căutări binare pe un set gata sortat. Containerele pot fi imbricate. De exemplu este perfect posibil să folosim un '''QMap&lt;QString,QList&lt;int&gt; &gt;''', unde cheia este '''QString''', iar valoarea este de tip '''QList&lt;int&gt;''' .
Containerele ''multi'' furnizează suport pentru valori asociate mai multor chei. Containerele ''hash'' furnizează căutări mai rapide utilizând funcții ''hash'' în loc de căutări binare pe un set gata sortat. Containerele pot fi imbricate. De exemplu este perfect posibil să folosim un '''QMap<QString,QList<int> >''', unde cheia este '''QString''', iar valoarea este de tip '''QList<int>''' .


==Inserarea de elemente într-un QList==
== Inserarea de elemente într-un QList ==


Există mai multe metode de a adăuga elemente într-un QList. Putem folosi operatorul '''&lt;&lt;''', sau putem folosi una dintre metodele :
Există mai multe metode de a adăuga elemente într-un QList. Putem folosi operatorul '''<<''', sau putem folosi una dintre metodele :


* '''void QList::prepend ( const QList&lt;T&gt; &amp; value )'''  - pentru a adăuga valoarea value  la începutul unei listei.  
* '''void QList::prepend ( const QList<T> & value )'''  - pentru a adăuga valoarea value  la începutul unei listei.  
* '''void QList::append ( const QList&lt;T&gt; &amp; value )'''  - pentru a adăuga valoarea value  la sfârșitul unei listei.
* '''void QList::append ( const QList<T> & value )'''  - pentru a adăuga valoarea value  la sfârșitul unei listei.
* '''void QList::insert ( int i, const T &amp; value )''' pentru a insera la poziția  i valoarea value.  
* '''void QList::insert ( int i, const T & value )''' - pentru a insera la poziția  i valoarea value.  


Un exemplu de aplicare al acestor metode îl aveți mai jos :<br />
Un exemplu de aplicare al acestor metode îl aveți mai jos :
<code>QList<QString> lista;
lista << "Romania";
qDebug() << lista;
lista.append("Franta");
qDebug() << lista;
lista.prepend("Italia");
qDebug() << lista;
lista.insert(1, "Olanda");
qDebug() << lista;
lista.insert(4, "Grecia");
qDebug() << lista;</code>


După fiecare operație efectuată asupra listei, afișăm conținutul listei și vom avea :<br />
După fiecare operație efectuată asupra listei, afișăm conținutul listei și vom avea :
<code>("Romania")
("Romania", "Franta")
("Italia", "Romania", "Franta")
("Italia", "Olanda", "Romania", "Franta")
("Italia", "Olanda", "Romania", "Franta", "Grecia")</code>


==Folosirea iteratorilor într-un QList==
== Folosirea iteratorilor într-un QList ==


Pentru a accesa elementele din cadrul unei liste avem la dispoziție 3 variante. Putem folosi
Pentru a accesa elementele din cadrul unei liste avem la dispoziție 3 variante. Putem folosi
* iteratorul inspirat din Java
* iteratorul inspirat din Java
* iteratorul inspirat din <span class="caps">STL</span> sau  
* iteratorul inspirat din STL sau  
* cuvântul cheie '''foreach'''.
* cuvântul cheie '''foreach'''.


Un exemplu de folosire al iteratorului inspirat din Java este mai jos :
Un exemplu de folosire al iteratorului inspirat din Java este mai jos :
<code>QListIterator<QString> i(lista);
while(i.hasNext()) qDebug() << i.next();</code>


În exemplul de mai sus se iterează de la începutul listei până la sfârșitul ei, dar la fel de bine această iterație se putea face de la sfârșitul listei până la începtul ei precum în exemplul următor  :
În exemplul de mai sus se iterează de la începutul listei până la sfârșitul ei, dar la fel de bine această iterație se putea face de la sfârșitul listei până la începtul ei precum în exemplul următor  :


Aceleași operații de iterație se pot face cu iteratorii inspirați din <span class="caps">STL</span>. Putem fie itera de la începutul listei până la sfârșitul ei precum în exemplu următor  :
<code>QListIterator<QString> i(lista);
i.toBack();
while(i.hasPrevious())qDebug() << i.previous();</code>
 
Aceleași operații de iterație se pot face cu iteratorii inspirați din STL. Putem fie itera de la începutul listei până la sfârșitul ei precum în exemplu următor  :
 
<code>QList<QString>::iterator i;
for(i = list.begin(); i != list.end(); +''i)qDebug() << (*i);</code>


, fie de la sfârșitul listei până la începutul acesteia :
, fie de la sfârșitul listei până la începutul acesteia :


Dacă doriți să iterați peste toate elementele conținute de o listă puteți folosi cuvântul cheie propriu frameworkului Qt '''foreach'''. El reprezintă un adaos la limbajul C++ și este implementat folosind preprocesorul. Sintaxa sa este* foreach('''''variabilă'',''container''''')*. Un exemplu de folosire îl găsiți mai jos :
<code>QList<QString>::iterator i = list.end();
while(i != list.begin()) { —i; qDebug() << (*i); } </code>


==Complexitatea algoritmică==
Dacă doriți să iterați peste toate elementele conținute de o listă puteți folosi cuvântul cheie propriu frameworkului Qt '''foreach'''. El reprezintă un adaos la limbajul C''+ și este implementat folosind preprocesorul. Sintaxa sa este* foreach('''''variabilă'',''container''''')*. Un exemplu de folosire îl găsiți mai jos :
 
<code>foreach(QString unElement,list) { qDebug() << unElement; }</code>
 
== Complexitatea algoritmică ==


Din punctul de vedere al complexității algoritmice, ne preocupă  rapiditatea în execuție a funcțiilor specifice diferitelor clase container. De exemplu inserarea unui element la mijlocul unui '''QLinkedList''' este o operație extrem de rapidă, indiferent de numărul de element conținute de această clasă.  În schimb inserarea aceluiași element la mijlocul unui '''QVector''' este extrem de lent, mai ales în cazul în care '''QVector''' conține mai multe elemente, din moment ce jumătate dintre elemente trebuie mutate o poziție. Atunci când ne alegem un container este recomandat să ținem cont de complexitatea algoritmică a diferitelor operații. În următorul tabel se facel un bilanț al complexității algoritmice a claselor de tip container secvențial.
Din punctul de vedere al complexității algoritmice, ne preocupă  rapiditatea în execuție a funcțiilor specifice diferitelor clase container. De exemplu inserarea unui element la mijlocul unui '''QLinkedList''' este o operație extrem de rapidă, indiferent de numărul de element conținute de această clasă.  În schimb inserarea aceluiași element la mijlocul unui '''QVector''' este extrem de lent, mai ales în cazul în care '''QVector''' conține mai multe elemente, din moment ce jumătate dintre elemente trebuie mutate o poziție. Atunci când ne alegem un container este recomandat să ținem cont de complexitatea algoritmică a diferitelor operații. În următorul tabel se facel un bilanț al complexității algoritmice a claselor de tip container secvențial.


[[Image:tabel2_Complexitate_container_secvential.JPG|Tabelul 1. Bilant al complexitatii algoritmice a claselor de tip container secvential]]
https://lh4.googleusercontent.com/-XEeiE7z9O8Y/TiKuGAltRAI/AAAAAAAAANI/zDre2fR_5KM/tabel2_Complexitate_container_secvential.JPG
 
'''Tabelul  1. Bilanț al complexității algoritmice a claselor de tip container secvențial'''
'''Tabelul  1. Bilanț al complexității algoritmice a claselor de tip container secvențial'''


Dar sunt anumite situații în care trebuie să folosim clase de tip container asociativ. În acest caz consultăm un tabel al bilanțurilor complexității algoritmice al acestor clase.
Dar sunt anumite situații în care trebuie să folosim clase de tip container asociativ. În acest caz consultăm un tabel al bilanțurilor complexității algoritmice al acestor clase.


[[Image:tabel1_Complexitate_container_asociativ.JPG|Tabelul 2. Bilant al complexitatii algoritmice a claselor de tip container secvential]]
https://lh3.googleusercontent.com/-U_bJ6TjGlGA/TiKuGPw8EVI/AAAAAAAAANM/L3PEChMYV10/tabel1_Complexitate_container_asociativ.JPG


'''Tabelul 2. Bilanț al complexității algoritmice a claselor de tip container asociativ'''
'''Tabelul 2. Bilanț al complexității algoritmice a claselor de tip container asociativ'''
===Categories:===
* [[:Category:Learning|Learning]]

Latest revision as of 12:47, 31 March 2015

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Containere și iteratori

Generalități

Qt are clase pentru a înlocui clasele C + + STL. Containerele Qt sunt clase șablon și pot conține orice alte clase mutabile. Aceste clase container au fost concepute pentru a fi mai compacte, mai sigure și mai ușor de folosit decât containerele STL. Ele sunt partajate implicit și pot fi apelate din mai multe threaduri. Există o largă gamă de containere, incluzând aici liste, stive, cozi, vectori asociativi și liste hash. Aceste clase conțin iteratori compatibili cu STL, cât și iteratori inspirați din Java. Iteratorii sunt obiecte care sunt utilizate pentru a se deplasa în cadrul unui container și pentru a obține acces la datele păstrate în el. Qt mai oferă de asemenea și cuvântul cheie foreach care face foarte facilă iterarea prin elementele conținute de o clasă container. Qt oferă următoarele containere secvenţiale:

  1. QList
  2. QLinkedList
  3. QVector
  4. QStack
  5. QQueue

Pentru majoritatea aplicaţiilor QList este cel mai recomdat. Dacă aveți nevoide de o listă înlănțuită utlizați QLinkedList; dacă doriți ca elementele să ocupe locuri consecutive în memorie se utilizează QVector. QStack şi QQueue oferă containeri cu semantică LIFO și FIFO.

Qt oferă de asemenea și containere asociative:

  1. QMap
  2. QMultiMap
  3. QHash
  4. QMultiHash
  5. QSet

Containerele multi furnizează suport pentru valori asociate mai multor chei. Containerele hash furnizează căutări mai rapide utilizând funcții hash în loc de căutări binare pe un set gata sortat. Containerele pot fi imbricate. De exemplu este perfect posibil să folosim un QMap<QString,QList<int> >, unde cheia este QString, iar valoarea este de tip QList<int> .

Inserarea de elemente într-un QList

Există mai multe metode de a adăuga elemente într-un QList. Putem folosi operatorul <<, sau putem folosi una dintre metodele :

  • void QList::prepend ( const QList<T> & value )  - pentru a adăuga valoarea value  la începutul unei listei.  
  • void QList::append ( const QList<T> & value )  - pentru a adăuga valoarea value  la sfârșitul unei listei.
  • void QList::insert ( int i, const T & value ) - pentru a insera la poziția  i valoarea value.  

Un exemplu de aplicare al acestor metode îl aveți mai jos :

QList<QString> lista;
lista << "Romania";
qDebug() << lista;
lista.append("Franta");
qDebug() << lista;
lista.prepend("Italia");
qDebug() << lista;
lista.insert(1, "Olanda");
qDebug() << lista;
lista.insert(4, "Grecia");
qDebug() << lista;

După fiecare operație efectuată asupra listei, afișăm conținutul listei și vom avea :

("Romania")
("Romania", "Franta")
("Italia", "Romania", "Franta")
("Italia", "Olanda", "Romania", "Franta")
("Italia", "Olanda", "Romania", "Franta", "Grecia")

Folosirea iteratorilor într-un QList

Pentru a accesa elementele din cadrul unei liste avem la dispoziție 3 variante. Putem folosi

  • iteratorul inspirat din Java
  • iteratorul inspirat din STL sau  
  • cuvântul cheie foreach.

Un exemplu de folosire al iteratorului inspirat din Java este mai jos :

QListIterator<QString> i(lista);
while(i.hasNext()) qDebug() << i.next();

În exemplul de mai sus se iterează de la începutul listei până la sfârșitul ei, dar la fel de bine această iterație se putea face de la sfârșitul listei până la începtul ei precum în exemplul următor  :

QListIterator<QString> i(lista);
i.toBack();
while(i.hasPrevious())qDebug() << i.previous();

Aceleași operații de iterație se pot face cu iteratorii inspirați din STL. Putem fie itera de la începutul listei până la sfârșitul ei precum în exemplu următor  :

QList<QString>::iterator i;
for(i = list.begin(); i != list.end(); +''i)qDebug() << (*i);

, fie de la sfârșitul listei până la începutul acesteia :

QList<QString>::iterator i = list.end();
while(i != list.begin()) { i; qDebug() << (*i); }
Dacă doriți să iterați peste toate elementele conținute de o listă puteți folosi cuvântul cheie propriu frameworkului Qt foreach. El reprezintă un adaos la limbajul C+ și este implementat folosind preprocesorul. Sintaxa sa este* foreach(variabilă,container)*. Un exemplu de folosire îl găsiți mai jos :
foreach(QString unElement,list) { qDebug() << unElement; }

Complexitatea algoritmică

Din punctul de vedere al complexității algoritmice, ne preocupă  rapiditatea în execuție a funcțiilor specifice diferitelor clase container. De exemplu inserarea unui element la mijlocul unui QLinkedList este o operație extrem de rapidă, indiferent de numărul de element conținute de această clasă.  În schimb inserarea aceluiași element la mijlocul unui QVector este extrem de lent, mai ales în cazul în care QVector conține mai multe elemente, din moment ce jumătate dintre elemente trebuie mutate o poziție. Atunci când ne alegem un container este recomandat să ținem cont de complexitatea algoritmică a diferitelor operații. În următorul tabel se facel un bilanț al complexității algoritmice a claselor de tip container secvențial.

tabel2_Complexitate_container_secvential.JPG Tabelul  1. Bilanț al complexității algoritmice a claselor de tip container secvențial

Dar sunt anumite situații în care trebuie să folosim clase de tip container asociativ. În acest caz consultăm un tabel al bilanțurilor complexității algoritmice al acestor clase.

tabel1_Complexitate_container_asociativ.JPG

Tabelul 2. Bilanț al complexității algoritmice a claselor de tip container asociativ