Úvod
Pole je rad rovnakých typov objektov v po sebe nasledujúcich polohách pamäte. Pole nemôže zvýšiť alebo skrátiť dĺžku. Vektor je ako pole, ale jeho dĺžka sa dá zväčšiť alebo zmenšiť. Vektor má teda oveľa viac operácií ako pole.
C ++ má veľa knižníc, ktoré všetky tvoria štandardnú knižnicu C ++. Jednou z týchto knižníc je kontajnerová knižnica. Kontajner je zbierka objektov a so zbierkou je možné vykonať určité operácie. Kontajnery C ++ je možné zoskupiť do dvoch sád: sekvenčné kontajnery a asociatívne kontajnery. Sekvenčné kontajnery sú vektor, pole (nie to isté pole, o ktorom sme hovorili predtým), deque, forward_list a list. Jedná sa o rôzne kolekcie (dátové štruktúry podobné poliam) a každá ponúka odlišné kompromisy.
Každý programátor by mal vedieť, ako sa rozhodnúť, či použije vektor, pole, deque, zoznam_predajov alebo zoznam. Ak programátor potrebuje štruktúru, ktorá vyžaduje viac operácií ako tie, ktoré sú spojené s bežným poľom, obyčajné pole by sa nemalo používať.
Ak úloha zahŕňa časté vkladanie a mazanie uprostred sekvencie, potom by sa mal použiť zoznam alebo zoznam forward_list. Ak úloha zahŕňa časté vkladanie a mazanie na začiatku alebo na konci sekvencie, mala by sa použiť deque. Ak tieto druhy operácií nie sú potrebné, mal by sa použiť vektor.
Tento článok vám ukáže, ako používať vektor C ++. Na pochopenie tohto článku budete potrebovať určité znalosti o ukazovateľoch, odkazoch a poliach v C ++.
Trieda a predmety
Trieda je skupina premenných a funkcií, ktoré spolupracujú, pričom premenným nie sú priradené hodnoty. Keď sú premenným priradené hodnoty, trieda sa stane objektom. Rôzne hodnoty dané tej istej triede majú za následok rôzne objekty; to znamená, že rôzne objekty môžu byť rovnakej triedy, ale môžu mať odlišné hodnoty. Vytvorenie objektu z triedy je tiež známe ako vytvorenie inštancie objektu.
Pojem vektor popisuje triedu. Objekt vytvorený z vektora má názov, ktorý vyberie programátor.
Na vytvorenie inštancie objektu z triedy je potrebná funkcia patriaca do triedy. V jazyku C ++ má táto funkcia rovnaký názov ako názov triedy. Rôzne objekty vytvorené (inštancované) z triedy majú odlišné názvy, ktoré každému z nich dal programátor.
Vytvorenie objektu z triedy znamená konštrukciu objektu; znamená to tiež inštanciu objektu.
Vektorová trieda
Vektorová trieda už bola definovaná a nachádza sa v knižnici. Ak chcete použiť triedu vektorov, programátor musí do súboru zahrnúť hlavičku vektora s nasledujúcou smernicou o predbežnom spracovaní:
#includePo zahrnutí hlavičky sa sprístupnia všetky vektorové prvky (dátové členy a členské funkcie). Ak chcete použiť objekt count na výstup údajov do terminálu (konzoly), musí byť tiež zahrnutá hlavička objektu. Ak chcete napísať program s vektorom, musia byť zahrnuté minimálne tieto hlavičky:
#include#include
Vytvorenie inštancie vektora
int foo [10];Hore je deklarácia poľa s názvom „foo“ a počtom prvkov „10.„Toto je pole celých čísel. Deklarácia vektora je podobná. Pre vektor je počet prvkov voliteľný, pretože dĺžka vektora sa môže zväčšovať alebo zmenšovať.
V tomto bode programu bola v knižnici už definovaná vektorová trieda a bola do nej zahrnutá hlavička. Vektor je možné vytvoriť pomocou nasledujúcich inštancií:
std :: vektorVektor je tu špeciálnej funkcie konštruktora. Typ údajov, ktoré bude vektor obsahovať, je „int“ v zátvorkách. Pojem „vtr“ je názov zvolený programátorom vektora. Nakoniec „8“ v zátvorkách predstavuje predbežný počet celých čísel, ktoré bude mať vektor.
Pojem „std“ znamená štandardný priestor mien. V tomto kontexte musí za týmto výrazom nasledovať dvojbodka. Ktokoľvek môže napísať svoju vlastnú knižnicu vektorových tried a používať ju. C ++ však už má štandardnú knižnicu so štandardnými názvami vrátane „vector.„Ak chcete použiť štandardný názov, štandardnému názvu musí predchádzať std :: . Ak sa chcete vyhnúť zadávaniu štandardného názvu programu std :: zakaždým, program môže začať nasledujúcim spôsobom:
#include#include
pomocou namespace std;
Preťaženie funkcie
Ak majú dva alebo viac rôznych podpisov funkcií rovnaký názov, je tento názov údajne preťažený. Keď sa volá jedna funkcia, počet a typ argumentov určuje, ktorá funkcia sa vykoná.
Konštrukcia vektora
Konštrukcia vektora znamená vytvorenie inštancie (vytvorenia) vektorového objektu. Funkcia konštruktora je preťažená nasledovne:
vektor
Tak sa vytvorí vektor s nulovou dĺžkou a typu „T.„Nasledujúce vyhlásenie vytvorí vektor s nulovou dĺžkou typu„ float “s názvom„ vtr: “
vektorvektor
Tak sa vytvorí vektor s n prvkami typu „T.„Pre tento vektor so štyrmi plavákovými prvkami je vyhlásenie:
vektorvektor
Tak sa vytvorí vektor n prvkov inicializovaný na hodnotu t. Nasledujúci príkaz vytvorí vektor 5 prvkov, kde každý prvok má hodnotu 3.4:
vektorKonštrukcia s inicializáciou
Vektor je možné zostrojiť (vytvoriť) a inicializovať súčasne jedným z nasledujúcich dvoch spôsobov:
vektorAlebo
vektorUpozorňujeme, že za menom objektu nie sú zátvorky. Zátvorky použité hneď za názvom objektu by mali mať zoznam inicializátorov, a to nasledovne:
vektorVektor je možné zostaviť a inicializovať neskôr pomocou zoznamu inicializátorov. V tomto prípade sa zátvorky nepoužijú:
vektorvtr = 1.1, 2.2, 3.3, 4.4;
vektor
Toto je konštruktor kópií. Vytvára vektor V2 ako kópiu vektora V1. Ilustruje to nasledujúci kód:
vektorvektor
Priradenie vektora počas výstavby
Počas výstavby je možné vytvoriť prázdny vektor, zatiaľ čo k nemu je priradený ďalší, a to nasledovne:
vektorvektor
Druhé vyhlásenie je ekvivalentné s:
vektorkonšt. vektor
Const vektor je vektor, ktorého prvky nie je možné meniť. Hodnoty v tomto vektore sú iba na čítanie. Po vytvorení sa vektor zobrazí takto:
konštantný vektorV tomto vektorovom type nemožno pridať ani odstrániť žiadny prvok. Navyše nie je možné meniť žiadnu hodnotu.
Stavba s Iterátorom
Šablóna poskytuje všeobecné zastúpenie pre dátový typ. Iterátor poskytuje všeobecnú reprezentáciu skenovania cez hodnoty kontajnera. Syntax na vytvorenie vektora s iterátorom je nasledovná:
šablónavektor (prvý InputIterator, posledný InputIterator, const Allocator & = Allocator ());
Týmto sa zostrojí vektor pre rozsah [prvý, posledný) pomocou zadaného alokátora, o ktorom sa bude diskutovať ďalej v tomto článku.
Zničenie vektora
Ak chcete zničiť vektor, jednoducho ho nechajte ísť mimo rozsah a ničenie sa spracuje automaticky.
Vektorová kapacita
size_type kapacita () const noexcept
Celkový počet prvkov, ktoré môže vektor obsahovať bez potreby opätovného pridelenia, je vrátený funkčnou členskou funkciou. Segment kódu je nasledovný:
vektorint num = vtr.kapacita ();
cout << num << '\n';
Výstup je 4.
rezerva (n)
Pamäťový priestor nie je vždy voľne dostupný. Extra miesto je možné rezervovať vopred. Zvážte nasledujúci segment kódu:
vektorvtr.rezerva (6);
cout << vtr.capacity() << '\n';
Výstup je 6. Rezervovaný ďalší priestor je teda 6 - 4 = 2 prvky. Funkcia vráti neplatnosť.
size () const noexcept
Týmto sa vráti počet prvkov vo vektore. Nasledujúci kód ilustruje túto funkciu:
vektorfloat sz = vtr.veľkosť ();
cout << sz << '\n';
Výstup je 4.
zmenšiť, aby sa zmestili()
Po pridelení ďalšej kapacity vektoru s funkciou reserve () je možné vektor zmenšiť, aby sa zmestil na pôvodnú veľkosť. Ilustruje to nasledujúci kód:
vektorvtr.rezerva (6);
vtr.zmenšiť, aby sa zmestili();
int sz = vtr.veľkosť ();
cout << sz << '\n';
Výstup je 4 a nie 6. Funkcia vráti neplatnosť.
resize (sz), resize (sz, c)
Týmto sa zmení veľkosť vektora. Ak je nová veľkosť menšia ako stará veľkosť, potom sa prvky na konci vymažú. Ak je nová veľkosť dlhšia, pridá sa ku koncu nejaká predvolená hodnota. Ak chcete mať konkrétnu pridanú hodnotu, použite funkciu resize () s dvoma argumentmi. Nasledujúci segment kódu ilustruje použitie týchto dvoch funkcií:
vektorvtr1.zmena veľkosti (2);
cout << "New size of vtr1: " << vtr1.size() << '\n';
vektor
vtr2.zmeniť veľkosť (4, 8.8);
cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
„<< vtr2[2] <<" "<< vtr2[3] << '\n';
Výstup je nasledujúci:
Nová veľkosť vtr1: 2vtr2: 1.1 2.2 8.8 8.8
Funkcie sa vrátia do platnosti.
empty () const noexcept
Táto funkcia vráti hodnotu 1 pre true, ak vo vektore nie sú žiadne prvky, a 0 pre false, ak je vektor prázdny. Ak má vektor 4 umiestnenia pre konkrétny typ údajov, napríklad float, bez akejkoľvek floatovanej hodnoty, potom tento vektor nie je prázdny. Ilustruje to nasledujúci kód:
vektorcout << vtr.empty() << '\n';
vektor
cout << vt.empty() << '\n';
vektor
cout << v.empty() << '\n';
Výstup je nasledujúci:
10
0
Prístup k prvkom vektora
Vektor je možné subskriptovať (indexovať) ako pole. Počítanie indexov sa začína od nuly.
vectorName [i]
Operácia „vectorName [i]“ vráti odkaz na prvok na ith index vektora. Nasledujúci kód vydáva 3.3 pre vyššie uvedený vektor:
vektorfloat fl = vtr [2];
cout << fl << '\n';
vectorName [i] konšt
Ak je vektor konštantný vektor, vykoná sa operácia „vectorName [i] const“ namiesto „vectorName [i]“. Táto operácia sa používa v nasledujúcom kóde:
konštantný vektorfloat fl = vtr [2];
cout << fl << '\n';
Výraz vráti konštantný odkaz na ith prvok vektora.
Priradenie hodnoty dolným indexom
Hodnotu je možné priradiť nekonštantnému vektoru nasledovne:
vektorvtr [2] = 8.8;
cout << vtr[2] << '\n';
Výstup je 8.8.
vectorName.o (i)
„NázovVektoru.at (i) “je ako„ vectorName [i] “, ale„ vectorName.v bode (i) “je spoľahlivejšie. Nasledujúci kód ukazuje, ako by sa mal tento vektor použiť:
vektorfloat fl = vtr.na (2);
cout << fl << '\n';
at () je vektorová členská funkcia.
vectorName.pri (i) konšt
„NázovVektoru.at (i) const “je ako„ vectorName [i] const “, ale„ vectorName.at (i) const “je spoľahlivejšie. „NázovVektoru.at (i) const “sa vykoná namiesto„ vectorName.at (i) “, keď je vektor konštantný vektor. Tento vektor sa používa v nasledujúcom kóde:
konštantný vektorfloat fl = vtr.na (2);
cout << fl << '\n';
at () const je vektorová členská funkcia.
Priradenie hodnoty funkciou at ()
Hodnotu je možné priradiť nekonštantnému vektoru pomocou funkcie at (), a to nasledovne:
vektorvtr.pri (2) = 8.8;
cout << vtr[2] << '\n';
Výstup je 8.8.
Problém s dolným skriptovaním
Problém so skriptovaním (indexovaním) spočíva v tom, že ak je index mimo rozsahu, môže sa vrátiť nula alebo sa môže za chodu vyskytnúť chyba.
predné ()
Týmto sa vráti odkaz na prvý prvok vektora bez odstránenia prvku. Výstup nasledujúceho kódu je 1.1.
vektorfloat fl = vtr.predné ();
cout << fl << '\n';
Element nie je odstránený z vektora.
predné () konšt
Keď pred vektorovou konštrukciou predchádza const, namiesto „front () sa vykoná výraz„ front () const “.„Používa sa v nasledujúcom kóde:
konštantný vektorfloat fl = vtr.predné ();
cout << fl << '\n';
Konštantná referencia sa vráti. Element nie je odstránený z vektora.
späť()
Týmto sa vráti odkaz na posledný prvok vektora bez odstránenia prvku. Výstup nasledujúceho kódu je 4.4.
vektorfloat fl = vtr.späť();
cout << fl << '\n';
späť () konšt
Keď pred vektorovou konštrukciou predchádza const, namiesto „back () sa vykoná výraz„ back () const “.„Používa sa v nasledujúcom kóde:
konštantný vektorfloat fl = vtr.späť();
cout << fl << '\n';
Konštantná referencia sa vráti. Element nie je odstránený z vektora.
Prístup k vektorovým údajom
data () noexcept; data () const noexcept;
Ktorýkoľvek z nich vracia ukazovateľ taký, že [data (), data () + size ()) je platný rozsah.
Tomu sa budem podrobnejšie venovať ďalej v článku.
Vracajúce sa iterátory a vektor
Iterátor je ako ukazovateľ, ale má viac funkcií ako ukazovateľ.
begin () noexcept
Vráti iterátor, ktorý ukazuje na prvý prvok vektora, ako v nasledujúcom segmente kódu:
vektorvektor
cout << *iter << '\n';
Výstup je 1.1. Upozorňujeme, že deklarácia, ktorá dostane iterátor, bola deklarovaná. Iterátor je dereferencovaný vo vratnom výraze, aby získal hodnotu rovnakým spôsobom, ako je dereferencovaný ukazovateľ.
begin () const noexcept;
Vráti iterátor, ktorý ukazuje na prvý prvok vektora. Keď pred vektorovou konštrukciou predchádza const, namiesto „begin () sa vykoná výraz„ begin () const “.„Za týchto podmienok nie je možné upraviť zodpovedajúci prvok vo vektore. Používa sa v nasledujúcom kóde:
konštantný vektorvektor
cout << *iter << '\n';
Výstup je 1.1. Upozorňujeme, že na príjem vráteného iterátora bol tentoraz použitý výraz „const_iterator“ namiesto iba „iterátor“.
end () noexcept
Vráti iterátor, ktorý smeruje bezprostredne za posledný prvok vektora. Zvážte nasledujúci segment kódu:
vektorvektor
cout << *iter << '\n';
Výstup je 0, čo nemá zmysel, pretože za posledným prvkom nie je žiadny konkrétny prvok.
end () const noexcept
Vráti iterátor, ktorý smeruje bezprostredne za posledný prvok vektora. Keď pred vektorovou konštrukciou predchádza „const“, namiesto „end () sa vykoná výraz„ end () const “.„Zvážte nasledujúci segment kódu:
konštantný vektorvektor
cout << *iter << '\n';
Výstup je 0. Upozorňujeme, že na príjem vráteného iterátora bol tentoraz použitý iba výraz „const_iterator“ namiesto iba „iterátor“.
Reverzná iterácia
Je možné mať iterátor, ktorý iteruje od konca až tesne pred prvý prvok.
rbegin () noexcept
Vráti iterátor, ktorý ukazuje na posledný prvok vektora, ako v nasledujúcom segmente kódu:
vektorvektor
cout << *rIter << '\n';
Výstup je 4.4.
Všimnite si, že bola deklarovaná deklarácia, ktorá dostane spätný iterátor. Iterátor je dereferencovaný vo vratnom výraze, aby získal hodnotu rovnakým spôsobom, ako je dereferencovaný ukazovateľ.
rbegin () const noexcept;
Vráti iterátor, ktorý ukazuje na posledný prvok vektora. Ak pred vektorovou konštrukciou stojí „const“, namiesto „rbegin () sa vykoná výraz„ rbegin () const “.„Za týchto podmienok nie je možné upraviť zodpovedajúci prvok vo vektore. Táto funkcia sa používa v nasledujúcom kóde:
konštantný vektorvektor
cout << *rIter << '\n';
Výstup je 4.4.
Všimnite si, že const_reverse_iterator bol tentokrát použitý, nie iba reverse_iterator, na príjem vráteného iterátora.
rend () noexcept
Vráti iterátor, ktorý smeruje tesne pred prvý prvok vektora. Zvážte nasledujúci segment kódu:
vektorvektor
cout << *rIter << '\n';
Výstup je 0, čo je nezmyselné, pretože bezprostredne pred prvým prvkom nie je žiadny konkrétny prvok.
rend () const noexcept
Vráti iterátor, ktorý smeruje tesne pred prvý prvok vektora. Ak pred vektorovou konštrukciou stojí „const“, namiesto „rend () sa vykoná výraz„ rend () const “.„Zvážte nasledujúci segment kódu:
konštantný vektorvektor
cout << *rIter << '\n';
Výstup je 0.
Všimnite si, že const_reverse_iterator bol tentokrát použitý, nie iba reverse_iterator, na príjem vráteného iterátora.
Vektorové modifikátory
Modifikátor, ktorý upravuje vektor, môže mať alebo vrátiť iterátor.
a.emplace (p, args)
Vloží objekt typu T skonštruovaný pomocou std :: forward
insert (iteratorPosition, value)
Vloží kópiu hodnoty na pozíciu iterátora vektora. Vráti iterátor (pozíciu) vo vektore, na ktorý bola umiestnená kópia. Nasledujúci kód ukazuje, kam bola hodnota umiestnená:
vektorvektor
++iter;
++iter;
vtr.vložka (iter, 25);
cout << vtr[1] << " << vtr[2]<< '
„ << vtr[3] << '\n';
Výstup je: 20 25 30.
Upozorňujeme, že iterátor bol pokročilý (zvýšený) rovnako ako ukazovateľ.
Môže sa tiež vložiť zoznam inicializátorov, ako ukazuje nasledujúci kód:
vektorvektor
++iter;
++iter;
vtr.vložiť (iter, 25, 28);
cout << vtr[1] << " << vtr[2]<< '
„ << vtr[3]<< " << vtr[4] << '\n';
Výstup je: 20 25 28 30.
vymazať (poloha)
Odstráni prvok na pozícii, na ktorú ukazuje iterátor, a potom vráti pozíciu iterátora. Ilustruje to nasledujúci kód:
vektorvektor
++iter;
++iter;
vtr.vymazať (iter);
cout << vtr[0] << " << vtr[1] << '
„ << vtr[2]<< '\n';
Výstup je: 10 20 40
push_back (t), push_back (rv)
Používa sa na pridanie jedného prvku na koniec vektora. Použite push_back (t) nasledovne:
vektorvtr.push_back (5.5);
float fl = vtr [4];
cout << fl << '\n';
Výstup je 5.5.
push_back (rv): - pozri neskôr.pop_back ()
Odstráni posledný prvok bez jeho vrátenia. Veľkosť vektora sa zníži o 1. Ilustruje to nasledujúci kód:
vektorvtr.pop_back ();
float sz = vtr.veľkosť ();
cout << sz << '\n';
Výstup je 3.
a.výmena (b)
Môžu byť zamenené dva vektory, ako je to znázornené v nasledujúcom segmente kódu:
vektorvektor
vtr1.swap (vtr2);
cout << "vtr1: "<< vtr1[0] <<" "<< vtr1[1] <<"
„<< vtr1[2] <<" "<< vtr1[3] << '\n';
cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
„<< vtr2[2] <<" "<< vtr2[3] << '\n';
Výstup je:
vtr1: 10 20 0 0vtr2: 1.1 2.2 3.3 4.4
Upozorňujeme, že ak je to potrebné, dĺžka vektora sa zvýši. Hodnoty, ktoré nemali nahradené, sa tiež nahradia nejakou predvolenou hodnotou.
jasný()
Odstráni všetky prvky z vektora, ako ukazuje nasledujúci segment kódu:
vektorvtr.jasný();
cout << vtr.size() << '\n';
Výstup je 0.
Subjekty rovnosti a vzťahu pre vektory
Prevádzkovateľ ==
Vráti hodnotu 1 pre true, ak majú dva vektory rovnakú veľkosť a zodpovedajúce prvky sú rovnaké; v opačnom prípade vráti hodnotu 0 za hodnotu false. Napríklad:
vektorvektor
bool bl = U == V;
cout << bl << '\n';
Výstup je 0.
The != Operátor
Vráti hodnotu 1 pre true, ak dva vektory nemajú rovnakú veľkosť a / alebo si zodpovedajúce prvky nie sú rovnaké; v opačnom prípade vráti hodnotu 0 za hodnotu false. Napríklad:
vektorvektor
bool bl = U!= V;
cout << bl << '\n';
Výstup je 1.
The < Operator
Vráti hodnotu 1 pre true, ak je prvý vektor počiatočnou podmnožinou druhého vektora, pričom prvky dvoch rovnakých častí sú rovnaké a v rovnakom poradí. Ak sú oba vektory rovnakej veľkosti a pohybujú sa zľava doprava a v prvom vektore sa vyskytne prvok, ktorý je menší ako zodpovedajúci prvok v druhom vektore, potom sa 1 vráti. V opačnom prípade sa vráti hodnota 0 pre hodnotu false. Napríklad:
vektorvektor
bool bl = U
Výstup je 1. < does not include the case when the size and order are the same.
Prevádzkovateľ
Vráti sa !(U < V), where U is the first vector and V is the second vector, according to the above definitions.
The <= Operator
Vráti U <= V, where U is the first vector and V is the second vector, according to the above definitions.
Operátor> =
Vráti sa !(U <= V), where U is the first vector and V is the second vector, according to the above definitions.
Záver
Vektor je príkladom kontajnera sekvencií. Vektor je „lepšou“ formou obyčajného poľa a vytvára sa z triedy. Vektory majú metódy, ktoré sú klasifikované podľa: konštrukcia a priradenie, kapacita, prístup k prvkom, prístup k dátam, iterátory, modifikátory a numerické preťažené operátory.
Existujú aj ďalšie sekvenčné kontajnery, ktoré sa nazývajú list, forward_list a array. Ak úloha zahŕňa časté vkladanie a mazanie uprostred sekvencie, potom by sa mal použiť zoznam alebo zoznam forward_list. Ak úloha zahŕňa časté vkladanie a mazanie na začiatku alebo na konci sekvencie, mala by sa použiť deque. Vektory by sa mali používať iba v prípade, že tieto druhy operácií nie sú dôležité.