Ievads
Masīvs ir to pašu objektu tipu virkne secīgās atmiņas vietās. Masīvs nevar palielināt rūdas garumu. Vektors ir kā masīvs, bet tā garumu var palielināt vai samazināt. Tāpēc vektoram ir daudz vairāk darbību nekā masīvam.
C ++ ir daudzas bibliotēkas, kuras visas veido C ++ standarta bibliotēku. Viena no šīm bibliotēkām ir konteineru bibliotēka. Konteiners ir objektu kolekcija, un ar kolekciju var veikt noteiktas darbības. C ++ konteinerus var sagrupēt divās grupās: secības konteineros un asociatīvajos konteineros. Secības konteineri ir vektors, masīvs (nav tas pats masīvs, kas tika apspriests iepriekš), deque, forward_list un saraksts. Tās ir dažādas kolekcijas (masīvam līdzīgas datu struktūras), un katra no tām piedāvā atšķirīgus kompromisus.
Jebkuram programmētājam būtu jāzina, kā izlemt, vai izmantot vektoru, masīvu, deque, forward_list vai sarakstu. Ja programmētājam nepieciešama struktūra, kurai nepieciešamas vairāk operāciju nekā tās, kas saistītas ar parasto masīvu, parasto masīvu nevajadzētu izmantot.
Ja uzdevums ir saistīts ar biežu ievietošanu un dzēšanu secības vidū, jāizmanto saraksts vai forward_list. Ja uzdevums ir saistīts ar biežu ievietošanu un dzēšanu secības sākumā vai beigās, jāizmanto deque. Ja šāda veida darbības nav nepieciešamas, jāizmanto vektors.
Šajā rakstā parādīts, kā izmantot vektoru C ++. Lai saprastu šo rakstu, jums būs nepieciešamas dažas zināšanas par C ++ rādītājiem, atsaucēm un masīviem.
Klase un objekti
Klase ir mainīgo un funkciju kopums, kas darbojas kopā, kur mainīgajiem nav piešķirtas vērtības. Kad mainīgajiem tiek piešķirtas vērtības, klase kļūst par objektu. Dažādas vērtības, kas piešķirtas tai pašai klasei, rada dažādus objektus; tas ir, dažādi objekti var būt vienā klasē, bet tiem ir atšķirīgas vērtības. Objekta izveide no klases ir pazīstama arī kā objekta instantizēšana.
Termins vektors apraksta klasi. No vektora izveidotam objektam ir nosaukums, kuru izvēlas programmētājs.
Funkcija, kas pieder klasei, ir vajadzīga, lai no klases izveidotu objektu. Programmā C ++ šai funkcijai ir tāds pats nosaukums kā klases nosaukumam. Dažādiem objektiem, kas izveidoti (eksemplāri) no klases, katram ir atšķirīgi nosaukumi, ko programmētājs piešķir.
Objekta izveide no klases nozīmē objekta konstruēšanu; tas nozīmē arī objekta instantizēšanu.
Vektoru klase
Vektoru klase jau ir definēta un atrodas bibliotēkā. Lai izmantotu vektoru klasi, programmētājam failā jāiekļauj vektora galvene ar šādu priekšapstrādes direktīvu:
# iekļautKad galvene ir iekļauta, visas vektora funkcijas (datu dalībnieki un dalībnieku funkcijas) kļūst pieejamas. Lai skaitīšanas objektu izmantotu datu izvadei uz termināli (konsoli), jāiekļauj arī objekta galvene. Lai rakstītu programmu ar vektoru, jāiekļauj vismaz šādas galvenes:
# iekļaut# iekļaut
Vektora instancēšana
int foo [10];Iepriekš ir masīva deklarācija ar nosaukumu “foo” un elementu skaitu “10.”Tas ir veselu skaitļu masīvs. Vektora deklarēšana ir līdzīga. Vektoram elementu skaits nav obligāts, jo vektora garums var palielināties vai samazināties.
Šajā programmas posmā vektoru klase jau ir definēta bibliotēkā, un galvene ir iekļauta. Vektoru var precizēt šādi:
std :: vektorsŠeit vektoram ir īpaša konstruktora funkcija. Datu veids, ko vektoris glabā, ir “int” leņķa iekavās. Termins “vtr” ir nosaukums, ko programmētājs izvēlējies vektoram. Visbeidzot, iekavās “8” ir provizoriskais skaitlis, kas vektoram būs.
Termins “std” apzīmē standarta nosaukumvietu. Šajā kontekstā šim apzīmējumam jāpievieno divkāršais kols. Ikviens var rakstīt savu vektoru klases bibliotēku un to izmantot. Tomēr C ++ jau ir standarta bibliotēka ar standarta nosaukumiem, ieskaitot “vektoru.”Lai izmantotu standarta nosaukumu, pirms standarta nosaukuma ir jābūt std :: . Lai izvairītos no standarta nosaukuma ierakstīšanas std :: katru reizi programmā, programmas failu var sākt šādi:
# iekļaut# iekļaut
izmantojot nosaukumvietu std;
Funkcijas pārslodze
Ja diviem vai vairākiem dažādu funkciju parakstiem ir vienāds nosaukums, tiek uzskatīts, ka šis nosaukums ir pārslogots. Izsaucot vienu funkciju, argumentu skaits un tips nosaka, kura funkcija tiek izpildīta.
Vektora konstruēšana
Vektora konstruēšana nozīmē vektora objekta instancēšanu (izveidošanu). Konstruktora funkcija ir pārslogota šādi:
vektors
Tādējādi tiek izveidots vektors, kura garums ir nulle un tips “T.”Šis apgalvojums izveido nulles garuma vektoru, kura tips ir“ pludiņš ”ar nosaukumu“ vtr: ”
vektorsvektors
Tādējādi tiek izveidots vektors ar n tipa “T” elementiem.Šim vektoram ar četriem pludiņa elementiem ir šāds paziņojums:
vektorsvektors
Tādējādi tiek izveidots n elementu vektors, kas inicializēts vērtībai t. Šis apgalvojums izveido 5 elementu vektoru, kur katram elementam ir vērtība 3.4:
vektorsKonstrukcija ar inicializāciju
Vektoru var konstruēt (izveidot) un inicializēt vienlaikus vienā no šiem diviem veidiem:
vektorsOr
vektorsŅemiet vērā, ka tikai aiz objekta nosaukuma nav iekavu. Iekavās, kas tiek izmantotas tieši pēc objekta nosaukuma, ir jābūt inicializētāju sarakstam šādi:
vektorsVektoru var konstruēt un inicializēt vēlāk ar inicializētāju sarakstu. Šajā gadījumā iekavas netiks izmantotas:
vektorsvtr = 1.1, 2.2, 3.3, 4.4;
vektors
Šis ir kopiju konstruktors. Tas izveido vektoru V2 kā vektora V1 kopiju. Šis kods ilustrē to:
vektorsvektors
Vektora piešķiršana būvniecības laikā
Konstrukcijas laikā var izveidot tukšu vektoru, kamēr tam tiek piešķirts cits:
vektorsvektors
Otrais apgalvojums ir līdzvērtīgs:
vektorsconst Vector
Konstanta vektors ir vektors, kura elementus nevar mainīt. Šī vektora vērtības ir tikai lasāmas. Izveidojot, vektors parādās šādi:
const vektorsŠajā vektora tipā nevienu elementu nevar pievienot vai noņemt. Turklāt nevienu vērtību nevar mainīt.
Konstruēšana ar Iterator
Veidne nodrošina vispārīgu datu veida attēlojumu. Atkārtotājs nodrošina vispārīgu skenēšanas attēlojumu, izmantojot konteinera vērtības. Sintakse, lai izveidotu vektoru ar iteratoru, ir šāda:
veidnevektors (vispirms InputIterator, pēdējais InputIterator, const Allocator & = Allocator ());
Tas konstruē vektoru diapazonam [pirmais, pēdējais], izmantojot norādīto sadalītāju, kas tiks aplūkots vēlāk šajā rakstā.
Vektora iznīcināšana
Lai iznīcinātu vektoru, vienkārši ļaujiet tam iziet no darbības jomas un iznīcināšana tiek veikta automātiski.
Vektora ietilpība
size_type kapacitāte () const noexcept
Kopējais elementu skaits, ko vektors var turēt, neprasot pārdalīšanu, tiek atgriezts ar kapacitātes dalībnieka funkciju. Tam ir šāds koda segments:
vektorsint num = vtr.ietilpība ();
cout << num << '\n';
Rezultāts ir 4.
rezerve (n)
Atmiņas vieta ne vienmēr ir brīvi pieejama. Papildu vietu var rezervēt iepriekš. Apsveriet šādu koda segmentu:
vektorsvtr.rezerve (6);
cout << vtr.capacity() << '\n';
Rezultāts ir 6. Tātad rezervētā papildu vieta ir 6 - 4 = 2 elementi. Funkcija atgriežas anulēta.
izmērs () const noexcept
Tas atgriež elementu skaitu vektorā. Šis kods parāda šo funkciju:
vektorspludiņš sz = vtr.Izmērs();
cout << sz << '\n';
Rezultāts ir 4.
shrink_to_fit ()
Pēc papildu jaudas piešķiršanas vektoram ar rezerves () funkciju vektoru var samazināt līdz tā sākotnējam lielumam. Šis kods ilustrē to:
vektorsvtr.rezerve (6);
vtr.shrink_to_fit ();
int sz = vtr.Izmērs();
cout << sz << '\n';
Rezultāts ir 4, nevis 6. Funkcija atgriežas anulēta.
mainīt izmēru (sz), mainīt izmēru (sz, c)
Tādējādi vektora izmērs tiek mainīts. Ja jaunais izmērs ir mazāks par veco izmēru, tad beigās esošie elementi tiek izdzēsti. Ja jaunais izmērs ir garāks, beigās tiek pievienota kāda noklusējuma vērtība. Lai iegūtu noteiktu pievienoto vērtību, izmantojiet funkciju resize () ar diviem argumentiem. Šis kodu segments ilustrē šo divu funkciju izmantošanu:
vektorsvtr1.mainīt izmēru (2);
cout << "New size of vtr1: " << vtr1.size() << '\n';
vektors
vtr2.mainīt izmēru (4, 8.8);
cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
"<< vtr2[2] <<" "<< vtr2[3] << '\n';
Rezultāts ir šāds:
Jauns vtr1: 2 izmērsvtr2: 1.1 2.2 8.8 8.8
Funkcijas zaudē spēku.
tukšs () const noexcept
Šī funkcija atgriež vērtību 1, ja vektorā nav elementu, un vērtību 0, ja vektors ir tukšs. Ja vektoram ir 4 atrašanās vietas noteiktam datu tipam, piemēram, pludiņam, bez pludiņa vērtības, tad šis vektors nav tukšs. Šis kods ilustrē to:
vektorscout << vtr.empty() << '\n';
vektors
cout << vt.empty() << '\n';
vektors
cout << v.empty() << '\n';
Rezultāts ir šāds:
10
0
Piekļuve vektora elementam
Vektoru var pakārtot (indeksēt) kā masīvu. Indeksa skaitīšana sākas no nulles.
vectorName [i]
Operācija “vectorName [i]” atgriež atsauci uz elementu ith vektora indekss. Šādas koda izejas 3.3 iepriekšminētajam vektoram:
vektorspludiņš fl = vtr [2];
cout << fl << '\n';
vectorName [i] const
Ja vektors ir nemainīgs vektors, tiek izpildīta operācija “vectorName [i] const” nevis “vectorName [i]”. Šī darbība tiek izmantota šādā kodā:
const vektorspludiņš fl = vtr [2];
cout << fl << '\n';
Izteiksme atgriež nemainīgu atsauci uz ith vektora elements.
Vērtības piešķiršana ar Subscript
Nepastāvīgam vektoram vērtību var piešķirt šādi:
vektorsvtr [2] = 8.8;
cout << vtr[2] << '\n';
Rezultāts ir 8.8.
vectorName.pie (i)
“VectorName.pie (i) ”ir līdzīgs“ vectorName [i] ”, bet“ vectorName.pie (i) ”ir ticamāka. Šis kods parāda, kā šis vektors jāizmanto:
vektorspludiņš fl = vtr.pie (2);
cout << fl << '\n';
at () ir vektora dalībnieka funkcija.
vectorName.pie (i) konst
“VectorName.at (i) const ”ir kā“ vectorName [i] const ”, bet“ vectorName.pie (i) const ”ir ticamāka. “VectorName.at (i) const ”tiek izpildīts“ vectorName ”vietā.pie (i) ”, kad vektors ir nemainīgs vektors. Šis vektors tiek izmantots šādā kodā:
const vektorspludiņš fl = vtr.pie (2);
cout << fl << '\n';
at () const ir vektora dalībnieka funkcija.
Vērtības piešķiršana funkcijai at ()
Vērtību var piešķirt nemainīgam vektoram ar funkciju at () šādi:
vektorsvtr.pie (2) = 8.8;
cout << vtr[2] << '\n';
Rezultāts ir 8.8.
Problēma ar apakškriptēšanu
Apakšskriptu (indeksēšanas) problēma ir tāda, ka, ja indekss ir ārpus diapazona, izpildes laikā var tikt atgriezta nulle vai izdota kļūda.
priekšā ()
Tas atgriež atsauci uz vektora pirmo elementu, nenoņemot elementu. Šī koda izeja ir 1.1.
vektorspludiņš fl = vtr.priekšpuse ();
cout << fl << '\n';
Elements netiek noņemts no vektora.
priekšpuse () konst
Kad vektora konstrukcijas priekšā ir konst, tiek izpildīts izteiciens “front () const”, nevis “front ().”Tas tiek izmantots šādā kodā:
const vektorspludiņš fl = vtr.priekšpuse ();
cout << fl << '\n';
Tiek atgriezta pastāvīga atsauce. Elements netiek noņemts no vektora.
atpakaļ ()
Tas atgriež atsauci uz vektora pēdējo elementu, nenoņemot elementu. Šī koda izeja ir 4.4.
vektorspludiņš fl = vtr.aizmugure ();
cout << fl << '\n';
atpakaļ () konst
Kad vektora konstrukcijas priekšā ir konst, tiek izpildīts izteiciens “back () const”, nevis “back ().”Tas tiek izmantots šādā kodā:
const vektorspludiņš fl = vtr.aizmugure ();
cout << fl << '\n';
Tiek atgriezta pastāvīga atsauce. Elements netiek noņemts no vektora.
Vektoru datu piekļuve
dati () noexcept; dati () const noexcept;
Jebkurš no šiem parametriem atgriež rādītāju, kurā [dati (), dati () + izmērs ()) ir derīgs diapazons.
Tas tiks detalizētāk aplūkots vēlāk rakstā.
Atgriešanās atkārtotāji un vektors
Iterators ir kā rādītājs, bet tam ir lielāka funkcionalitāte nekā rādītājam.
sākt () noexcept
Atgriež atkārtotāju, kas norāda uz vektora pirmo elementu, kā tas ir šajā kodu segmentā:
vektorsvektors
cout << *iter << '\n';
Rezultāts ir 1.1. Ņemiet vērā, ka deklarācija, kas saņem atkārtotāju, ir deklarēta. Atgriešanas izteiksmē iterators tiek novirzīts, lai iegūtu vērtību tādā pašā veidā kā novirzīts rādītājs.
sākt () const noexcept;
Atgriež atkārtotāju, kas norāda uz vektora pirmo elementu. Kad vektora konstrukcijas priekšā ir konst, tiek izpildīts izteiciens “sākt () konst”, nevis “sākt ().”Saskaņā ar šo nosacījumu vektorā atbilstošo elementu nevar modificēt. Tas tiek izmantots šādā kodā:
const vektorsvektors
cout << *iter << '\n';
Rezultāts ir 1.1. Ņemiet vērā, ka šoreiz tiek izmantots “const_iterator”, nevis tikai “iterator”, lai saņemtu atgriezto iteratoru.
beigas () noexcept
Atgriež atkārtotāju, kas norāda tieši aiz vektora pēdējā elementa. Apsveriet šādu koda segmentu:
vektorsvektors
cout << *iter << '\n';
Rezultāts ir 0, kas ir bezjēdzīgs, jo aiz pēdējā elementa nav konkrēta elementa.
end () const noexcept
Atgriež atkārtotāju, kas norāda tieši aiz vektora pēdējā elementa. Kad vektora konstrukcijas priekšā ir “const”, tiek izpildīts izteiciens “end () const”, nevis “end ().Apsveriet šādu koda segmentu:
const vektorsvektors
cout << *iter << '\n';
Rezultāts ir 0. Ņemiet vērā, ka, lai saņemtu atgriezto iteratoru, šoreiz tika izmantots “const_iterator”, nevis tikai “iterator”.
Reversā atkārtojums
Ir iespējams izveidot iteratoru, kas atkārtojas no gala līdz tieši pirms pirmā elementa.
rbegin () noexcept
Atgriež atkārtotāju, kas norāda uz vektora pēdējo elementu, tāpat kā šādā koda segmentā:
vektorsvektors
cout << *rIter << '\n';
Rezultāts ir 4.4.
Ņemiet vērā, ka deklarācija, kas saņem reverso atkārtotāju, ir deklarēta. Atgriešanas izteiksmē iterators tiek novirzīts, lai iegūtu vērtību tādā pašā veidā kā novirzīts rādītājs.
rbegin () const noexcept;
Atgriež atkārtotāju, kas norāda uz vektora pēdējo elementu. Kad vektora konstrukcijas priekšā ir “const”, tiek izpildīts izteiciens “rbegin () const”, nevis “rbegin ().”Saskaņā ar šo nosacījumu vektorā atbilstošo elementu nevar modificēt. Šī funkcija tiek izmantota šādā kodā:
const vektorsvektors
cout << *rIter << '\n';
Rezultāts ir 4.4.
Ņemiet vērā, ka atgrieztā iteratora saņemšanai šoreiz tika izmantots nevis reverss_iterators, bet konst_reverse_iterator.
rend () noexcept
Atgriež iteratoru, kas norāda tieši pirms vektora pirmā elementa. Apsveriet šādu koda segmentu:
vektorsvektors
cout << *rIter << '\n';
Rezultāts ir 0, kas ir bezjēdzīgs, jo tieši pirms pirmā elementa nav konkrēta elementa.
rend () const noexcept
Atgriež iteratoru, kas norāda tieši pirms vektora pirmā elementa. Kad vektora konstrukcijas priekšā ir “const”, tiek izpildīts izteiciens “rend () const”, nevis “rend ().Apsveriet šādu koda segmentu:
const vektorsvektors
cout << *rIter << '\n';
Rezultāts ir 0.
Ņemiet vērā, ka atgrieztā iteratora saņemšanai šoreiz tika izmantots nevis reverss_iterators, bet konst_reverse_iterator.
Vektoru modifikatori
Modifikators, kas modificē vektoru, var ņemt vai atgriezt iteratoru.
a.emplace (p, args)
Ievieto T veida objektu, kas izveidots ar std :: forward
ievietot (iteratorPosition, value)
Ievieto vērtības kopiju vektora iteratora pozīcijā. Atgriež iteratoru (pozīciju) vektorā, kur ievietota kopija. Šis kods parāda, kur ir ievietota vērtība:
vektorsvektors
++atkārtot;
++atkārtot;
vtr.ievietot (iter, 25);
cout << vtr[1] << " << vtr[2]<< '
" << vtr[3] << '\n';
Rezultāts ir: 20 25 30.
Ievērojiet, ka iterators bija uzlabots (palielināts) tāpat kā rādītājs.
Var ievietot arī inicializētāju sarakstu, kā parāda šāds kods:
vektorsvektors
++atkārtot;
++atkārtot;
vtr.ievietot (iter, 25, 28);
cout << vtr[1] << " << vtr[2]<< '
" << vtr[3]<< " << vtr[4] << '\n';
Rezultāts ir: 20 25 28 30.
dzēst (pozīcija)
Noņem elementu pozīcijā, uz kuru norāda iterators, pēc tam atgriež iteratora pozīciju. Šis kods ilustrē to:
vektorsvektors
++atkārtot;
++atkārtot;
vtr.dzēst (atkārtot);
cout << vtr[0] << " << vtr[1] << '
" << vtr[2]<< '\n';
Rezultāts ir: 10 20 40
push_back (t), push_back (rv)
Izmanto, lai vektora beigās pievienotu vienu elementu. Izmantojiet push_back (t) šādi:
vektorsvtr.push_back (5.5);
pludiņš fl = vtr [4];
cout << fl << '\n';
Rezultāts ir 5.5.
push_back (rv): - skatīt vēlāk.pop_back ()
Noņem pēdējo elementu, to neatdodot. Vektora lielums tiek samazināts par 1. Šis kods ilustrē to:
vektorsvtr.pop_back ();
pludiņš sz = vtr.Izmērs();
cout << sz << '\n';
Rezultāts ir 3.
a.apmainīt (b)
Divus vektorus var apmainīt, kā parādīts šādā kodu segmentā:
vektorsvektors
vtr1.mijmaiņas (vtr2);
cout << "vtr1: "<< vtr1[0] <<" "<< vtr1[1] <<"
"<< vtr1[2] <<" "<< vtr1[3] << '\n';
cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
"<< vtr2[2] <<" "<< vtr2[3] << '\n';
Rezultāts ir:
vtr1: 10 20 0 0vtr2: 1.1 2.2 3.3 4.4
Ņemiet vērā, ka, ja nepieciešams, vektora garums tiek palielināts. Arī vērtības, kurām nebija aizstājēju, aizstāj ar kādu noklusējuma vērtību.
skaidrs ()
Noņem no vektora visus elementus, kā parāda šāds koda segments:
vektorsvtr.skaidrs ();
cout << vtr.size() << '\n';
Rezultāts ir 0.
Vienlīdzība un sakaru operatori vektoriem
== Operators
Atgriež vērtību 1, ja abiem vektoriem ir vienāds izmērs un atbilstošie elementi ir vienādi; pretējā gadījumā tas atgriež 0 par nepatiesu. Piemēram:
vektorsvektors
bool bl = U == V;
cout << bl << '\n';
Rezultāts ir 0.
The != Operators
Atgriež vērtību 1, ja abiem vektoriem nav vienāda lieluma un / vai attiecīgie elementi nav vienādi; pretējā gadījumā tas atgriež 0 par nepatiesu. Piemēram:
vektorsvektors
bool bl = U!= V;
cout << bl << '\n';
Rezultāts ir 1.
The < Operator
Atgriež vērtību 1, ja pirmais vektors ir otrā vektora sākotnējā apakškopa, un divu vienādu daļu elementi ir vienādi un vienā secībā. Ja abi vektori ir vienāda lieluma un pārvietojas no kreisās uz labo un pirmajā vektorā ir sastopams elements, kas ir mazāks par atbilstošo elementu otrajā vektorā, 1 joprojām tiks atgriezts. Pretējā gadījumā 0 par false tiek atgriezta. Piemēram:
vektorsvektors
bool bl = U
Rezultāts ir 1. < does not include the case when the size and order are the same.
Operators
Atgriežas !(U < V), where U is the first vector and V is the second vector, according to the above definitions.
The <= Operator
Atgriež U <= V, where U is the first vector and V is the second vector, according to the above definitions.
Operators> =
Atgriežas !(U <= V), where U is the first vector and V is the second vector, according to the above definitions.
Secinājums
Vektors ir secības konteinera piemērs. Vektors ir “labāka” parastā masīva forma, un tas tiek iegūts no klases. Vektoriem ir metodes, kuras klasificē: konstruēšana un piešķiršana, jauda, piekļuve elementiem, piekļuve datiem, iteratori, modifikatori un skaitliski pārslogoti operatori.
Ir arī citi secības konteineri, kurus sauc par sarakstu, uz priekšu_ saraksts un masīvs. Ja uzdevums ir saistīts ar biežu ievietošanu un dzēšanu secības vidū, jāizmanto saraksts vai forward_list. Ja uzdevums ir saistīts ar biežu ievietošanu un dzēšanu secības sākumā vai beigās, jāizmanto deque. Tāpēc vektorus vajadzētu izmantot tikai tad, ja šāda veida operācijas nav svarīgas.