Click here to load reader

Dzisiejszy wykład

  • View
    37

  • Download
    3

Embed Size (px)

DESCRIPTION

Dzisiejszy wykład. Standardowa biblioteka języka C++ STL ( Standard Template Library ). STL – ogólne spojrzenie. Kolekcje. Klasy które zawierają inne obiekty. Iteratory. „Wskaźniki” do elementów kolekcji, używane do indeksowania kolekcji. Adaptery. - PowerPoint PPT Presentation

Text of Dzisiejszy wykład

Programowanie obiektoweatwa w uyciu, o bardzo duych moliwociach i efektywna
Programowanie uogólnione, nie obiektowe
Adaptery
Iteratory
Kolekcje
Kolekcja wartoci typu T indeksowana przez unikatowe wartoci typu Key
map<Key,T>
set<Key>
Liniowy czas dostpu, zmienna dugo, stay czas wstawiania/usuwania w dowolnym miejscu listy
list<T>
deque<T>
vector<T>
Niektóre funkcje skadowe wystpuj we wszystkich kolekcjach, np.:
size() zwraca liczb elementów w kontenerze
push_back() dodaje obiekt „na kocu” kontenera
Dostp bezporedni do danych w kolekcjach
poprzez operator[] lub skadow at()
Iteratory
metoda dostpu do elementów kolekcji, z uyciem ptli i „indeksu”
wiele rónych iteratorów: jednokierunkowy, odwrotny, stay itd.
*
Wzorzec vector zachowuje si jak dynamicznie alokowana tablica, ale dodatkowo umoliwia dynamiczn zmian rozmiaru (przy dodawaniu elementów przez insert() lub push_back())
1.unknown
vector<T> V(n,value);
vector<T> V(n);
Wzorzec vector posiada równie przeciony konstruktor kopiujcy i operator przypisania wykonujce gbokie kopiowanie
*
Uwaga: pojemno wektora nie zwiksza si automatycznie przy dostpie przy pomocy operatora indeksowania. Uycie metod insert() oraz push_back() do dodania elementów tablicy powikszy j w miar potrzeby.
#include <iostream>
using namespace std;
iVector[Count] = Count;
Indeksowanie wzorca vector
W najprostszym przypadku, obiekt typu vector moe by uywany jako prosta tablica z dynamiczn alokacj pamici
Brak sprawdzania zakresu indeksu
Brak dynamicznego rozszerzania. Bdny indeks spowoduje bd dostpu (jeli mamy szczcie)
Uycie skadowej at() spowoduje wyjtek out_of_range w tej sytuacji
int MaxCount = 100;
vector<int> iVector(MaxCount);
cout << iVector[Count];
int MaxCount = 100;
vector<int> iVector(MaxCount);
cout << iVector.at(Count);
Iterator jest deklarowany dla konkretnego typu kolekcji i jego implementacja jest zalena od tego typu oraz nie ma szczególnego znaczenia dla uytkownika
Iteratory s podstaw wielu algorytmów STL i s niezbdnym narzdziem do dobrego wykorzystania kolekcji STL
*
Iterator wektora zachowuje si jak wskanik do dynamicznie zaalokowanej tablicy
vector<T> v;
do something with *idx
iteratory jednokierunkowe - definiuj tylko ++
iteratory dwukierunkowe - definiuj ++ i --
dodawanie i odejmowanie liczby cakowitej r+n, r-n
zmian o liczb cakowit r+=n, r-=n
odejmowanie iteratorów r-s zwraca liczb cakowit
kolekcja posiada operator indeksowania []
iteratory do staej - *p nie pozwala na zmian elementu kolekcji
iteratory do zmiennej - umoliwiaj zmiany w kolekcji
for (p = v.begin(); p != v.end(); ++p)
*p = new value
Iteratory odwrotne - pozwalaj na przegldanie elementów kolekcji od koca do pocztku
reverse_iterator rp;
process *rp
Iteratory do staej musz by uyte dla staych kontenerów - przewanie przekazywanych jako parametry
Typ jest zdefiniowany w konenerze: vector<T>::const_iterator
void ivecPrint(const vector<int>& V, ostream& Out) {
vector<int>::const_iterator It; // MUST be const
for (It = V.begin(); It != V.end(); ++It) {
cout << *It;
Wektor Copy ma pocztkowo zerowy rozmiar. push_back() powikszy docelowy wektor do odpowiednich rozmiarów
Stosujemy przedrostkowy, a nie przyrostkowy operator inkrementacji iteratora
string DigitString = "45658228458720501289";
vector<int> BigInt;
BigInt.push_back(DigitString.at(i) - '0');
Copy.push_back(*It);
*
string DigitString = "45658228458720501289";
vector<int> BigInt;
BigInt.push_back(DigitString.at(i) - '0');
Wska na pierwszy element BigInt i skopiuj go
Przesu si do drugiego elementu BigInt
Teraz It nie wskazuje na aden element BigInt.
Próba wyuskania moe spowodowa bd dostpu.
Cofnij si do ostatniego elementu BigInt
*
Wstawianie elementów na kocu wektora (z uyciem push_back()) jest najbardziej efektywne.
Wstawianie w innym miejscu wymaga przesuwania danych w pamici
Wektor zachowuje si jak tablica o zmiennej dugoci
Wstawianie elementów do wektora powiksza zaalokowany obszar np. dwa razy
Wstawienie elementu uniewania wszystkie iteratory wskazujce na elementy po punkcie wstawiania
Realokacja (powikszenie) wektora uniewania wszystkie iteratory do elementów danego wektora
*
Skadowa insert()
W dowolnym miejscu wektora mona wstawi element uywajc iteratora i skadowej insert()
Jest to najgorszy przypadek;
pocztku sekwencji, co maksymalnie
zwiksza liczb kopiowanych elementów
vector<int> Y;
Y.insert(Y.begin(), m);
Tak samo jak wstawianie, kasowanie elementów wektora wymaga przesuni jego elementów (poza szczególnym przypadkiem ostatniego elementu)
Usuwanie ostatniego elementu: V.pop_back()
Usuwanie uniewania iteratory do elementów po punkcie usuwania, a wic
j = V.begin();
maj ten sam rozmiar
Klasa elementu wektora musi posiada operator porównania
Dla innych porówna klasa elementu musi posiada odpowiedni operator (<, >, ...)
*
Umoliwia wstawianie/usuwanie dowolnych elementów posugujc si iteratorami
Oprócz metod klasy vector posiada dodatkowo metody push_front() i pop_front()
Wikszo metod i konstruktorów identyczna jak dla wektora
Wymaga pliku nagówkowego <deque>
Nie umoliwia dostpu swobodnego, ale umoliwia wstawianie i usuwanie elementów na dowolnej pozycji w staym czasie
Pewne rónice w metodach w stosunku do wektora i deque (np. brak operatora indeksowania)
Wstawianie i usuwanie elementów nie uniewania iteratorów
*
A[0],...,A[Size-1]
A["alfred"], A["judy"]
*
Wartoci (obiekty) w kolekcji s przechowywane w porzdku posortowanym pod wzgldem typu klucza
wartoci Key mog si powtarza
multimap<Key,T>
map<Key,T>
multiset<Key>
set<Key>
Zbiory i wielozbiory
Zarówno wzorzec set jak i multiset przechowuje wartoci typu key, który musi mie zdefiniowane uporzdkowanie
set umoliwia przechowywanie jedynie pojedynczych obiektów, natomiast multiset umoliwia przechowywanie duplikatów
typ klucza musi definiowa operator <
set<int> iSet; // fine, built-in type has < operator
set<Employee> Payroll; // class Employee did not
// implement a < operator
return (ID < Other.ID);
void PrintEmployee(Employee toPrint, ostream& Out);
int main() {
set<Employee>::const_iterator It;
Out<<*It<<endl;
vector moe by uyty zamiast dynamicznie alokowanej tablicy
list umozliwia dynamiczn zmian rozmiaru przy dostpie sekwencyjnym
set moe by uyty w przypadku potrzeby posortowania danych i braku koniecznoci dostpu swobodnego
map powinien by uyty, kiedy dane musz by indeksowane przy pomocy unikatowego klucza
*
cout << "% ";
for (idx = v.begin (); idx != v.end (); ++idx)
cout << *idx << endl;
total = total + *idx;
*
cout << "% ";
for_each (v.begin (), v.end (), print);
cout << "Sum = " << total << endl;
Implementuj sortowanie, wyszukiwanie i inne podstawowe operacje
Trzy typy algorytmów operujcych na kolekcjach sekwencyjnych
modyfikujce algorytmy na cigach
niemodyfikujce algorytmy na cigach
count(), count_if(), find(), for_each()
Dostp do kolekcji uzyskiwany za porednictwem iteratora
Zaoenie
Styl programowania zaprezentowany tutaj nazywany jest programowaniem uogólnionym (generic programming)
Pisanie funkcji zalenych od pewnych operacji zdefiniowanych na przetwarzanych typach
Na przykad, find() polega na operatorze == dostpnym dla typu danych
Dla poszczególnych funkcji, mówimy o zbiorze typów które mog by uywane z dan funkcj
np. find() moe by uyta dla wszystkich typów, dla których jest zdefiniowany operator ==
*
STL jest bardzo elastyczna, umoliwia przechowywanie danych dowolnych typów w kolekcjach
Kolekcja nie zwalnia pamici zaalokowanej na obiekty, do których przechowuje wskaniki
vector< int > v;
int av = *vi;
Foo * av = *vi;
Obiekty funkcyjne w STL
Obiekt funkcyjny to obiekt, który ma zdefiniowany operator wywoania funkcji (), tak e w poniszym przykadzie
wyraenie fo() jest wywoaniem operatora () obiektu fo, a nie wywoaniem funkcji fo
Obiektów funkcyjnych moemy uy we wzorcach STL wszdzie tam, gdzie dopuszczalny jest wskanik do funkcji
Zamiast
piszemy
Obiekty funkcyjne - po co ta komplikacja?
Obiekty funkcyjne maj nastpujce zalety w porównaniu ze wskanikami do funkcji
Obiekt funkcyjny moe posiada stan. Mona mie dwa egzemplarze obiektu funkcyjnego, które mog by w rónych stanach. Nie jest to moliwe w przypadku funkcji
*
{
bool operator() (const T & w) {
return w > reference;
vector
jVector[41]; // get member
jVector.capacity(); // capacity of container
jVector.empty();
deklaracja
iteratora:
*idx; // access to element pointed by idx
idx++; // moves pointer to next element
idx--; // moves pointer to previous element
void fill(iterator,
iterator, T)
iterator fill_n(iterator,
int, T)
void generate(iterator,
iterator, function)
char nextLetter() {
T min_element(iterator,
function for_each
(iterator, iterator,
int count(iterator,
iterator, T)
int count_if(iterator,
iterator, function)
Jak wyej, ale do porównania uywa funkcji
Binarne wyszukiwanie w kolekcji.
if (r == v.end())
iterator find(iterator,
iterator, function)
bool binary_search
Uyteczne w poczeniu z ostream_iterator
ostream_iterator<int> output(cout, " ");
copy(v.begin(), v.end(), output);