Dariusz Wardowski
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 2/19
Klasa string
Klasa string umieszczona w standardowej bibliotece odpowiada za różnego rodzaju operacje na łaocuchach.
string s0; //łańcuch o długości 0 string s1(„Ala ma kota”);
string s2(10,’x’); //utworzy łańcuch „xxxxxxxxxx”
string s3(„Nie lubie C++”,4,9); //”lubie C++”
string s4(„Ciekawy wyklad?”,14); //”Ciekawy wyklad”
string s5(&s4[0],&s4[5]); //”Ciek”
Operatory
+
cout << string(„Ala”) + string(„ ma”) + string(„ kota”);
cout << s1 + s3;
=
s2 = s3;
s4 = ’d’;
[]
string s(„Tekst”);
cout << s[2]; // ‘k’
<, ==, !=
string t1(„abc”);
string t2(„abd”);
cout << (t1 < t2) << (t1 == t2) << (t1 != t2) << endl;
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 4/19
length() i size()
Za pomocą tych metod odczytujemy długośd łaocucha.
string s(„baaaaaaaaaaaaaaaaaardzo dlugi string”);
cout << s.size() << endl;
cout << s.length() << endl;
Obydwie funkcje zwracają długośd łaocucha bez znaku kooca.
Funkcja length() pochodzi ze starszych wersji klasy string, natomiast funkcja size() zgodna jest z biblioteką STL.
STL (Standard Template Library)
STL to biblioteka szablonów zawierająca:
kontenery – pełniące rolę analogiczną do tablic, czyli przechowują obiekty tego samego typu iteratory – obiekty umożliwiające przeglądanie elementów w kontenerze
obiekty funkcyjne – działaniem przypominające funkcje, inaczej funktory, mogą byd obiektami klas lub wskaźnikami do funkcji.
algorytmy – czyli grupa instrukcji wykonująca określone zadanie.
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 6/19
vector
vector to klasa szablonowa, której obiekty pozwalają na przechowywanie obiektów tego samego typu. Alokacja pamięci następuje w sposób dynamiczny.
#include <vector>
int main() {
vector<double> liczby(10);
for (int i=0; i<10; i++) liczby[i]=i*i;
return 0;
}
Iterator klas kontenerowych
Każda klasa kontenerowa posiada iterator, czyli mechanizm, który przypomina działanie wskaźnika. W szczególności iterator może byd wskaźnikiem, lecz również może byd obiektem dla którego zdefiniowano odpowiednie metody pozwalające działad jak wskaźnik.
vector<double> liczby(10);
for (int i=0; i<10; i++) liczby[i]=i*i;
vector<double>::iterator it; //definicja iteratora
it = liczby.begin(); //ustawienie iteratora na pierwszy element for (int i=0; i<liczby.size(); i++) //określenie wielkości
// konteneru {
cout << *it << endl; //operator wyłuskania
it++; //iterator wskazuje na nastepny element }
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 8/19
begin() i end()
Metoda begin() zwraca iterator wskazujący na pierwszy element kontenera.
Metoda end() zwraca iterator wskazujący na element, który znajduje się za ostatnim elementem kontenera, element ten nazywany jest elementem ograniczającym.
it = liczby.begin();
while (it != liczby.end()) {
cout << *it << endl;
it++;
}
push_back
Jest to jedna z metod, która należy tylko do niektórych klas kontenerowych (np. do vector).
Metoda ta umożliwia dodanie elementu na koniec konteneru.
vector<char> znaki; //tworzy pusty wektor char z;
while (cin >> z && z!=‘a’) znaki.push_back(z);
for (int i=0; i < znaki.size(); i++) cout << znaki[i];
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 10/19
erase
Metoda erase powoduje usunięcie elementów kontenera. Usuwane elementy wskazywane są przez iteratory będące argumentami.
vector<bool> taknie(4);
taknie[0]=taknie[2] = false;
taknie[1]=taknie[3] = true;
taknie.erase(taknie.begin()++, taknie.begin()+2);
for (int i=0; i<taknie.size(); i++) cout << taknie[i] << endl;
erase(it1, it2) usunie elementy kontenera zaczynając od elementu na który wskazuje it1 aż do elementu występującego przed elementem wskazywanym przez iterator it2;
insert
Dzięki metodzie insert możemy wstawid elementy z jednego kontenera do drugiego.
vector<string> s1;
s1.push_back(„Ala”);
s1.push_back(„ma”);
s1.push_back(„kota”);
vector<string> s2;
s2.push_back(„Janek”);
s2.push_back(„ma”);
s2.push_back(„kota”);
s2.push_back(„i”);
s2.push_back(„psa”);
s1.insert(s1.end(),s2.begin()+3,s2.end());
vector<string>::iterator it;
it = s1.begin();
while (it != s1.end()) {
cout << *it << " ";
it++;
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 12/19
Funkcje biblioteki STL
Bibliotek STL poza klasami szablonowymi, zawiera również funkcje, które nie są związane z żadną klasą. Jednakże każda klasa z tej biblioteki może tego typu funkcje wykorzystywad.
Poniżej przedstawiono przykładowe funkcje STL-owe, które nie są związane z klasami.
for_each();
random_shuffle();
sort();
random_shuffle
Jest to funkcja dwuargumentowa pobierająca dwa iteratory określające zakres obiektów jakie mają byd rozmieszczone w sposób losowy.
vector<int> w(10);
for (int i=0; i<10; i++) w[i] = 5*i;
srand (unsigned(time(NULL)));
random_shuffle(w.begin()+1, w.end());
Powyższy kod spowoduje rozmieszczenie w sposób losowy elementów o wartościach od 5 do 45.
Element 0 (czyli pierwszy) zostanie na swoim miejscu.
random_shuffle może byd zastosowany dla tych kontenerów, dla których możliwy jest losowy dostęp (operator *+).
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 14/19
sort
Funkcja sort powoduje posortowanie w kolejności rosnącej elementów danego kontenera w zakresie podanym przez dwa iteratory. Do porównywania elementów używany jest operator <.
vector<int> w(10);
for (int i=0; i<10; i++) w[i] = 5*i;
sort(w.begin(),w.end());
sort
class A {
int x;
public:
A() {}
int getx() {return x;}
A(int _x) : x(_x) {}
friend bool operator<
(const A & a1, const A & a2) {
if (a1.x<a2.x) return true;
return false;
} };
int main() {
vector<A> g(10);
for (int i=0; i<10; i++) {
g[i] = A(i+10);
}
sort(g.begin(),g.end());
for (int i=0; i<10; i++) {
cout << g[i].getx() << " ";
}
return 0;
}
W przypadku, gdy kontener zawiera obiekty typu zdefiniowanego przez użytkownika, należy pamiętad o zdefiniowaniu funkcji operator<().
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 16/19
Więcej kontenerów
Biblioteka STL posiada wiele rodzajów kontenerów. Kontenery te różnią się typami. Poniżej przedstawiono listę nazw różnych typów kontenerów:
• vector
• deque
• list
• queue
• priority_queue
• stack
• map
• multimap
• set
• multiset
• bitset
Wszystkie powyższe typy kontenerów służą do przechowywania obiektów. W ramach jednego konteneru wszystkie obiekty muszą byd tego samego typu.
Funktory
Funktory, czyli obiekty funkcyjne to dowolne obiekty dla których zdefiniowano operator ().
Poniżej przedstawiono przykład funktora:
class A {
private:
int x;
public:
A(int _x) : x(_x) {}
int operator()(int y) {return x*y;}
};
A a(10);
int z = a(30); //obiekt a jest funktorem
dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 18/19
for_each
Poniżej przedstawiono przykład użycia funktora na przykładzie funkcji for_each.
void f(int & x) {
x *= 2;
}
int main() {
vector<int> W;
W.push_back(1);
W.push_back(8);
W.push_back(12);
for_each(W.begin(),W.end(),f);
cout << W[0] << " " << W[1] << " " << W[2] << endl;
return 0;
}