1 / 36

Rozdział 11. Klasy kontenerów

1) Kontenery sekwencyjne 2) Kontenery asocjacyjne 3) Algorytmy 4) String s , Byte Arrays i Variants. Rozdział 11. Klasy kontenerów.

mac
Download Presentation

Rozdział 11. Klasy kontenerów

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 1) Kontenery sekwencyjne 2) Kontenery asocjacyjne 3) Algorytmy 4) Strings, Byte Arrays i Variants Rozdział 11.Klasy kontenerów

  2. Kontener lub inaczej pojemnik to taka struktura danych, której głównym zadaniem jest przechowywanie w zorganizowany sposób zbioru danych (obiektów). Kontener zapewnia narzędzia dostępu takie jak dodawanie, usuwanie czy wyszukiwanie obiektów w kontenerze. Kontenery różnią się wydajnością poszczególnych operacji. Na podstawie Wikipedii Pojęcie kontenera

  3. 1) Działają tak samo na wszystkich platformach 2) Zawierają łatwy w użyciu iterator zainspirowany językiem Java 3) Na niektórych platformach sprzętowych wspieranych przez Qtopia Core, kontenery Qt są jedynymi kontenerami jakich można używać 4) Implicit sharing (copy on write)‏ Zalety kontenerów QT

  4. 1) QVector<T> - tablica, która przechowuje kolejne pozycje w sąsiadujących ze sobą komórkach pamięci QVector<double> vect(2)‏ vect[0] = 1.0; vect[1] = 0.5678; QVector<double> vect; vect.append(1.0); vect.append(0.5678); Można użyć operatora << zamiast append(); vect << 1.0 << 0.5678; Kontenery sekwencyjne

  5. Przeglądanie wektora double sum = 0.0; for(int i = 0; i < vect.count(); ++i) sum += vect[i];

  6. 2) QLinkedList<T> - przechowuje kolejne dane w nie sąsiadujących ze sobą komórkach pamięci. QLinkedList<T> jest bardziej wydajny niż QVector<T> w przypadku dodawania lub usuwania składników z początku lub środka struktury. QLinkedList<QString> list; list.append(„aaa”); list.append(„ccc”); QLinkedList<QString>::iterator i = list.find(„ccc”); list.insert(i,”bbb”); Zamiast operatora [] musimy w przypadku QLinkedList używać iteratorów.

  7. 3) QList<T> - stanowi kombinację największych zalet QVector<T> i QLinkedList<T>. Ma interfejs oparty na indeksach. 4)QStringList<T> - jest podklasą klasy QList<QString>. Wprowadza kilka dodatkowych funkcji, dzięki czemu staje się wygodniejsza przy obsłudze napisów. 5) QStack<T> - push(), pop(), top()‏ 6) QQueue<T> - enqueue(), dequeue(), head()‏

  8. 1) Typem prostym: int, double 2) Wskaźnikiem 3) Klasą która ma domyślny konstruktor, konstruktor kopiujący, operator przypisania 4) Kontenerem (Qlist<QVector<double> >list;)‏ Czym może być <T>

  9. Qt wprowadza dwie kategorie iteratorów służących do przeglądania danych znajdujących się w kontenerze: 1) iteratory w stylu języka Java 2) iteratory w stylu Standard Template Library (STL)‏ Kategorie iteratorów

  10. 1) Read-only iterator: QVectorIterator<T>, QLinkedListIterator<T> and QListIterator<T> 2) Read-write iterator: QMuatbleVectorIterator<T>, QMutableLinkedListIterator<T>, QMutableListIterator<T> Iteratory w stylu języka Java:

  11. Typowa pętla: QList<double> list; ... QListIterator<double> i(list); while (i.hasNext()) { do_something(i.next()); } QListIterator<T>

  12. Usuwanie wszystkich liczb ujemnych z kontenera: QMutableListIterator<double> i(list); while(i.hasNext()){ if (i.next() < 0.0) i.remove(); } Zastępowanie liczb ujemnych ich wartością bezwzględną: QMutableListIterator<double> i(list); while (i.hasNext()){ int val = i.next(); if (val < 0.0) i.setValue(-val); }

  13. W Qt występują dwa rodzaje iteratorów w stylu STL: 1) C<T>::iterator 2) C<T>::const_iterator Iterator C<T>::const_iterator nie pozwala nam na modyfikowanie danych. Iteratory w stylu STL

  14. W przypadku iteratorów w stylu STL możemy posługiwać się operatorami ++ lub -- w celu przemieszczania się po kolejnych elementach struktury. Operator * pozwala nam dostać się do wartości, na która wskazuje iterator.

  15. Przykład zastępowania wartości ich wartościami bezwzględnymi: QList<double>::iterator i = list.begin(); while(i!=list.end())‏ { *i = qAbs(*i); ++i; }

  16. Przeglądanie kontenerów zwracanych przez funkcje: Poprawny sposób: QList<int> list = splitter->sizes(); QList<int>::const_iterator i = list.begin(); while(i!=list.end())‏ {do_something(*i); ++i;} Niepoprawny sposób: QList<int>::const_iterator i = splitter->sizes().begin(); while(i!=splitter->sizes().end())‏{ do_something(*i); ++i; } Używając iteratorów w stylu STL należy zawsze przeglądać kopie kontenera zwróconego przez wartość

  17. Używając iteratorów w stylu języka Java nie musimy tworzyć żadnych kopii. Wszystko odbywa się bez naszego udziału: QListIterator<int> i(splitter->sizes()); while(i.hasNext())‏ { do_something(i.next()); }

  18. QVector<double> sineTable() { QVector<double> vect(360) for (int i=0; i<360; i++) vect[i] = sin(i/2*M_PI)); return vect; } QVector<double> table = sineTable(); void sineTable(vector<double> &vect) { vect.resize(360); for (int i=0; i<360; ++i;) vect[i] = sin(i/(2*M_PI)); } Vector<double> table; sineTable(table);

  19. Zalety: 1) Kopiowanie jest tak szybkie jak w przypadku kopiowania pojedyńczego wskaźnika 2) Nie wymaga żadnego dodatkowego działania ze strony programisty (nie musi się niczym przejmować)‏ 3) Zachęca do stosowania przejrzystego stylu programowania, gdzie obiekty są zwracane przez wartość Implicit sharing (copy on write)‏

  20. Qstring str1 = „AAA”; Qstring str2 = str1; Licznik referencji = 2 dla pierwszej struktury. str2[0] = 'D'; Licznik referencji dla obu struktur danych wynosi 1. str1 = str2 Licznik referencji dla pierwszej struktury danych wynosi 0 i ta struktura danych jest usuwana z pamięci. Dla drugiej struktury licznik referencji wynosi teraz 2. Implicit Sharing gwarantuje, że dane nie będą kopiowane, jeżeli nie zostaną zmodyfikowane. Jak działa Implicit Sharing?

  21. Jeszcze jedna metoda przeglądania elementów w kontenerze sekwencyjnym (pętla foreach): QLinkedList<Movie> list; ... foreach(Movie movie,list)‏ { if(movie.title()==”Citizen Kane”)‏ { cout << „Found Citizen Kane” << endl; break; } }

  22. Kontenery asocjacyjne przechowują dowolną liczbę elementów tego samego typu, indeksowanych po kluczu. Qt wprowadza dwie główne klasy kontenerów asocjacyjnych: QMap<K,T> i QHash<K,T> Kontenery Asocjacyjne

  23. QMap<K,T> - struktura danych, która przechowuje pary klucz-wartość w porządku rosnącym kluczy. Dodawanie elementów: QMap<QString,int> map; map.insert(„seven”,7); // lub alternatywnie map[„seven”] = 7; Wydobywanie danych: int val = map.value(„seven”); //lub alternatywnie możemy posłużyć się operatorem [], QMultiMap<int,QString> multiMap; multiMap.insert(1,”one”); multiMap.insert(1,”jeden”); QList<QString>vals = multiMap.values(1); QMap<K,T>

  24. Instrukcja: int seconds = map.value(„delay”,30); Jest równoważna instrukcjom: Int seconds = 30; If(map.contains(„delay”)) seconds = map.value(„delay”);

  25. QHash<K,T> - struktura danych, która przechowuje pary klucz-wartość w tablicy haszowej. Umożliwia szybszy przegląd danych niż QMap<K,T>. QHash<K,T> jest nieuporządkowany. reserve() – określamy jak wiele elementów będzie przechowywanych w strukturze. squeeze() - zmniejszamy rozmiar struktury. QHash<K,T>

  26. QMap<QString,int>map; ... int sum = 0; QMapIterator<QString,int>i (map); while(i.hasNext())‏ sum+=i.next().value(); QMapIterator<QString,int>i map(); while(i.hasNext())‏ { i.next(); if(i.value()>largestValue)‏ { largestKey=i.key(); largestValue = i.value(); } } Klucz i wartość są dostępne poprzez funkcje key() i value()‏

  27. <QtAlgorithms> - nagłówek ten deklaruje zbiór globalnych szablonów funkcji, które implementują podstawowe algorytmy na kontenerach. <algorithm> - nagłówek ten wprowadza bardziej kompletny zbiór algorytmów. Te algorytmy mogą być używane zarówno na kontenerach Qt jak i kontenerach STL. Algorytmy

  28. qFind() - wyszukuje podaną przez nas wartość w kontenerze: QStringList l; l << „Emma” << „Karl” << „James”; QStringList::iterator i = qFind(l.begin(),l.end(),”Karl”); qBinaryFind – algorytm ten zakłada, że dane w strukturze są posortowane i dzięki czemu może zastosować szybkie wyszukiwanie binarne qFill() - wypełnia kontener określonymi wartościami: QLinkedList<int> list(10); qFill(list.begin(),list.end(),1009); Przykłady zastosowań algorytmów

  29. qCopy() - kopiuje wartości z jednego kontenera do drugiego. Może być również używany do kopiowania wartości w tym samym kontenerze. QVector<int> vect(list.count()); qCopy(list.begin(),list.end(),vect.begin()); qSort() - sortuje elementy kontenerze. qSort(list.begin(),list.end()); qSort(list.begin(),list.end(),qGreater<int>()); qStableSort() - podobny do qSort(), ale dodatkowo gwarantuje, że elementy które miały taką samą wartość przed sortowaniem będą miały taką samą kolejność po sortowaniu. Przykłady zastosowań algorytmów c.d.

  30. qDeleteAll() - wywołuje delete na każdym wskaźniku przechowywanym w kontenerze. qDeleteAll(list); list.clear(); qSwap() - wymienia wartości pomiędzy dwoma zmiennymi. int x1 = line.x1(); int x2 = line.x2(); if(x1>x2)‏ qSwap(x1,x2); Przykłady zastosowań algorytmów c.d.

  31. QString – struktura danych przypominająca wektor i służąca do przechowywania obiektów typu QChar. 1) length(), append(), sprintf(), arg(), number(), setNum(), toInt(), toLong(), toDouble(), mid(), left(), right(), indexOf(), startsWith(), endsWith(), toUpper(), toLower(), replace(), remove(), insert(), trimmed(), simplified(), split(), join(), isEmpty(), toAscii(), fromAscii(), toLatin(), fromLatin(); 2) operatory: +, += Strings, Byte Arrays and Variants

  32. QString str = „User: ”; str += userName+”\n”; QString str = „User: ”; str.append(userName); str.sprintf(„%s%.1f%%,”perfect competition”,100.0); str = QString::number(59.6); str.setNum(59.6); Bool ok; Double d = str.toDouble(&ok); QString str = „Ala ma kota” qDebug() << str.mid(3,4); qDebug() << str.left(8) << „” << str.right(9); int i = str.indexOf(„middle”);

  33. If ((url.startsWith(„http:”) && url.endsWith(„.png”))‏ if(fileName.toLower() == „readme.txt”)‏ QString str = „a cloudy day”; str.replace(2,6,”sunny”); str.remove(2,6); str.insert(2,”sunny”); str.replace(„&”,”&amp”); QString str = „ BOB \t THE \nDOG \n”; qDebug() << str.trimmed(); qDebug() << str.simplified(); QString str = „polluter pays principle”; QStringList words = str.split(„ „); str = words.join(„\n”);

  34. QByteArray: 1) left(), right(), mid(), toLower(), toUpper(), Trimmed(), aimplified()‏ 2) Do przechowywania surowych danych binarnych 3) Brak wsparcia dla Unicodu. QByteArray

  35. QVariant: 1) Służy do przechowywania danych różnych typów w jednej zmiennej 2) Możemy organizować dane w sposób jaki tylko chcemy QMap<QString, Qvariant> pearMap; pearMap[„Standard”] = 1.95; pearMap[„Orgranic”] = 2.25; QMap<QString,QVariant> fruitMap; fruitMap[„Orange”] = 2.10; fruitMap[„Pineapple”] = 3.85; fruitMa[„Pear”] = pearMap; QVariant

  36. KONIEC Rozdział opracowany na podstawie książki pod tytułem: C++ GUI Programming with Qt Krzysztof Środoń

More Related