Dokumentacja kontenera vector
Kompletna dokumentacja kontenera
vector w języku polskim znajduje się na łamach niniejszego serwisu w dziale
dokumentacji.
Co to jest vector?
Vector jest to tak zwany
kontener na dane(pojemnik), inaczej dynamiczna tablica. W owej tablicy mamy dostęp do każdego jej elementu oraz możemy w każdym momencie zwiększać jej wielkość.
Jakimi funkcjami posługujemy się używając vectora?
Pierwszy program używający vector'a.
Kod przykładowego programu:
#include <iostream>
#include <vector>
int main()
{
std::vector < int > tab;
int x = 0;
for( int i = 0; i < 10; i++ )
{
tab.push_back( x );
x = x + 2;
}
for( int i = 0; i < tab.size(); i++ )
{
std::cout << tab[ i ] << std::endl;
}
return 0;
}
A teraz o co w tym wszystkim chodzi:
Nagłówek zawierający vector zawsze musimy napisać tą linijkę zanim rozpoczniemy pracę z dynamicznymi tablicami.
int x = 0;
for( int i = 0; i < 10; i++ )
{
tab.push_back( x );
x = x + 2;
}
Najpierw deklarujemy zmienną o nazwie x, którą będzie zapełniany nasz Vector. Następnie rozpoczyna się pętla mająca 10 obrotów. Funkcja push_back rozszerza naszą tablicę na końcu o jeden jej element, a następnie wpisuje do niego wartość podaną w nawiasie.
for( int i = 0; i < tab.size(); i++ )
{
std::cout << tab[ i ] << std::endl;
}
Tutaj znów rozpoczynamy pętlę. Następnie odczytujemy wartości dynamicznej tablicy, a z pomocą przychodzi nam funkcjia
size() zwracająca jej wielkość. Warto zauważyć, iż odczyt dynamicznej tablicy odbywa się w taki sam sposób jak i zwykłej tablicy.
I tu kończymy nasz program linijką return 0 i nawiasem.
Zapisywanie danych do pojemnika
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
int main()
{
std::vector < int > tab;
srand( time( NULL ) );
tab.push_back( 0 );
for( int i = 0; i < 10; i++ )
{
int gdzie = rand() % tab.size();
tab.insert( tab.begin() + gdzie, i );
}
for( int i = 0; i < tab.size(); i++ )
{
std::cout << tab[ i ] << std::endl;
}
return 0;
}
Tłumaczenie:
int gdzie = rand() % tab.size();
tab.insert( tab.begin() + gdzie, i );
Najpierw losujemy liczbę, którą później wykorzystujemy do wybrania odpowiedniego miejsca dla zapisu zmiennej i. Widzimy funkcję
insert(), jest ona nieco czasochłonna jednak w wielu wypadkach niezastąpiona. Otóż musi ona najpierw rozszerzyć tablicę, następnie przesunąć określone elementy w następne miejsce, a dopiero na końcu zapisuje podaną wartość do pustego elementu tablicy. Bardzo ważna jest też funkcja tab.begin() wskazująca na pierwszy element tablicy. Bez niej nasz program by się nie skompilował. Do dyspozycji zamiast
tab.begin() mamy, także funkcję
tab.end() wskazującą na ostani element tablicy. Ważne jest też by przed użyciem tych dwóch funkcji tablica miała chociaż jeden element. Jeżeli nie będzie go posiadać zaraz po uruchomieniu naszej aplikacji, program zamknie się lub zawiesi.
Sortowanie zawartości kontenerów z użyciem algorithm
Użyjemy kodu z poprzedniego programu, a więc:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
int main()
{
std::vector < int > tab;
srand( time( NULL ) );
tab.push_back( 0 );
for( int i = 0; i < 10; i++ )
{
int gdzie = rand() % tab.size();
tab.insert( tab.begin() + gdzie, i );
}
sort( tab.begin(), tab.end() );
for( int i = 0; i < tab.size(); i++ )
{
std::cout << tab[ i ] << std::endl;
}
return 0;
}
Nie ma co wiele tłumaczyć jedynie dwie linijki:
Tutaj znajduje się dla nas ważna funkcja
sort(), więc jeżeli chcemy jej używać musimy dodać tą linijkę.
sort( tab.begin(), tab.end() );
Funkcja
sort() sortuje zawartość kontenera, w parametrach podajemy funkcje wskazujące na odpowiednie miejsca w pojemniku przeznaczone do sortowania. Zazwyczaj jest to początek i koniec, jednak możemy zastosować cos takiego:
sort( tab.begin() + 5, tab.end() );
Tworzenie tablicy obiektow własnej klasy
Vector umożliwia nam też tworzenie pojemnika obiektów naszej własnej klasy. Powinieneś, a właściwie musisz znać klasy, oraz konstruktory w c++, aby prawidłowo zrozumieć tą część artykułu.
Artykuł o klasach w C++.
Artkuł o konstruktorach klasy w C++.
Oto przykład, kod:
#include <iostream>
#include <vector>
#include <string>
#include <conio.h>
using namespace std;
class czlowiek
{
public:
string imie;
string nazwisko;
string numer;
czlowiek( string ximie, string xnazwisko, string xnumer );
};
int main()
{
vector < czlowiek > osoba;
cout << "Baza Osob\n1.-Lista osob\n2.-Dodaj osobe\n3.-Wyjscie";
char odp;
do
{
odp = getch();
switch( odp )
{
case '1':
cout << "\n\n\nLista osob:\n";
for( int i = 0; i < osoba.size(); i++ )
{
cout << endl;
cout << "Nazwa: " << osoba[ i ].imie << endl;
cout << "Autor: " << osoba[ i ].nazwisko << endl;
cout << "Numer tel.: " << osoba[ i ].numer << endl;
}
break;
case '2':
cout << "\n\n\n|----DODAWANIE_OSOBY_DO_LISTY-----|";
cout << "\nPodaj imie: ";
string odp_imie;
cin >> odp_imie;
cout << "Nazwisko: ";
string odp_nazwisko;
cin >> odp_nazwisko;
cout << "Numer tel.: ";
string odp_numer;
cin >> odp_numer;
osoba.push_back( czlowiek( odp_imie, odp_nazwisko, odp_numer ) );
cout << "\n<***ZAKONCZONO_Z_SUKCESEM***>";
break;
}
} while( odp != '3' );
return 0;
}
czlowiek::czlowiek( string ximie, string xnazwisko, string xnumer )
: imie( ximie )
, nazwisko( xnazwisko )
, numer( xnumer )
{
}
Kod powyżej pokazuje użycie kontenerów w praktyce. Myślę, że Ci się przyda, gdyż najważniejsze jest to by umieć czegoś używać pisząc swój projekt.
Więcej o funkcjach vectora
Teraz przedstawię program zawierający funkcje które też są bardzo ważne, a ich wcześniej nie przedstawiłem:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
vector < int > tab;
srand( time( NULL ) );
for( int i = 0; i < 12; i++ )
tab.push_back( rand() % 100 );
sort( tab.begin(), tab.end() );
cout << "Pojemnik przed edycja: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
tab.pop_back();
cout << "\nPojemnik po wywolaniu funkcji pop_back: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
tab.resize( 8 );
cout << "\nPojemnik po wywolaniu funkcji resize: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
cout << "\nTrzeci element tablicy przed erase: " << tab[ 2 ] << "\n";
tab.erase( tab.begin() + 2 );
cout << "Trzeci element tablicy po erase: " << tab[ 2 ] << "\n";
cout << "\nTablica przed erase z dwoma parametrami:\n";
for( int i = 0; i < tab.size(); i++ )
std::cout << tab[ i ] << std::endl;
tab.erase( tab.begin() + 1, tab.begin() + 4 );
cout << tab.size();
cout << "\nTablica po erase z dwoma parametrami:\n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
tab.clear();
cout << "\nZawartosc pojemnika po clear: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
return 0;
}
Tłumaczenie:
for( int i = 0; i < 12; i++ )
tab.push_back( rand() % 100 );
sort( tab.begin(), tab.end() );
cout << "Pojemnik przed edycja: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
Zapełniamy tablicę losowymi elementami, później sortujemy ich wartość.
Na końcu wyświetlamy zawartość pojemnika.
tab.pop_back();
cout << "\nPojemnik po wywolaniu funkcji pop_back: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
Jak widzimy funkcja
pop_back() usuwa ostatni element dynamicznej tablicy.
tab.resize( 8 );
cout << "\nPojemnik po wywolaniu funkcji resize: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
Funkcja
resize() zmienia wielkość vectora do podanej w nawiasie.
cout << "\nTrzeci element tablicy przed erase: " << tab[ 2 ] << "\n";
tab.erase( tab.begin() + 2 );
cout << "Trzeci element tablicy po erase: " << tab[ 2 ] << "\n";
Funkcja
erase() z podanym jednym parametrem, czyli adresem określonego elementu, usuwa go. Pamiętajmy że begin()+3 nie oznacza 3 elementu, a 4 ponieważ sama funkcja begin zwraca iterator do 1 elementu.
UWAGA! Elementy znajdujące się za elementem usuniętym zostaną przesunięte
odpowiedno na jego miejsce.
cout << "\nTablica przed erase z dwoma parametrami:\n";
for( int i = 0; i < tab.size(); i++ )
std::cout << tab[ i ] << std::endl;
tab.erase( tab.begin() + 1, tab.begin() + 4 );
cout << tab.size();
cout << "\nTablica po erase z dwoma parametrami:\n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
Funkcji
erase() można też używać podając dwa parametry. Zostaje wtedy usunięty
ciąg elementów pomiędzy podanymi adresami wraz z podanymi adresami.
tab.clear();
cout << "\nZawartosc pojemnika po clear: \n";
for( int i = 0; i < tab.size(); i++ )
cout << tab[ i ] << std::endl;
return 0;
}
Funkcja
clear() całkowicie czyści tablicę nie zostawiając w niej żadnego elementu.
Iterator w dynamicznej talicy
Co to jest iterator
Iterator w vectorze jest to swego rodzaju wskaźnik wskazujący na określony element tablicy. Możemy go edytować oraz z jego pomocą odwoływać się do określonego elementu tablicy.
Kiedy go używamy?
Iteratora w vectorze używamy do wskazywania na określony element tablicy.
Używaliśmy już iteratora w naszych programach m.in funkcja
begin() zwraca iterator do pierwszego elementu tablicy.
Przykładowy program używający iteratora
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector < int > tab;
for( int i = 0; i < 10; i++ )
tab.push_back( i );
vector < int >::iterator it_tab = tab.begin();
for(; it_tab != tab.end(); it_tab++ )
cout <<* it_tab;
}
Tłumaczenie:
vector < int >::iterator it_tab = tab.begin();
for(; it_tab != tab.end(); it_tab++ )
cout <<* it_tab;
Na początku deklarujemy i definiujemy nasz iterator. Następnie z pomocą pętli for i iterator odczytujemy dane naszej tablicy. Warto zauważyć, że można łatwo zmieniać adres na który wskazuje nasz iterator dodawaniem itp. Iteratorem posługujemy się podobnie jak wskaźnikiem o czym świadczy gwiazdeczka. ;)
Zakończenie
Zakończyliśmy już lekcję o vectorze, jednym z bardziej przydatnych narzędzi STL-a. Teraz będziesz mógł pisać swoje programy nie określając z góry wielkości tablicy.