VECTOR(DINAMIČKI NIZ) U C++
Deklaracija niza je:
Ovde se mora navesti u uglastoj zagradi dimenzija(3) koja se dalje ne može menjati.
Za razliku od lista kod vektora se dimenzija može menjati u toku programa.
Uključivanje datoteke vector
using namespace std;
U suprotnom bi svaki put kad se želi pozvati vector moralo pisati std::vector
Primer upotrebe vectora:
using namespace std;
vector < int > a(10);
Ovde je:
- vector-identifikacija vektora
- <int> - tip podataka koji se koriste u vektoru, u ovom slučaju celobrojni
- a - naziv vektora
a[3]
Osnovna manipulacija std::vector u C++
U ovom primeru ilustrujemo kako koristiti std::vector za dinamičko upravljanje nizom podataka.
Demonstriramo dodavanje elemenata pomoću push_back, prolazak kroz vektor koristeći
opseg-baziranu petlju i dobijanje veličine vektora pomoću size().
#include <vector>
using namespace std;
int main() {
vector<int> numbers;
// Adding elements to the vector
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// Printing vector elements
cout << "Vector elements: ";
for (int num : numbers) {
cout << num << " ";
}
// Number of elements
cout << "\nVector size: " << numbers.size() << endl;
return 0;
}
Metode vektora
Dodavanje elementa na kraj vektora
primer dodavanja broja 13 na kraj vektora a:
Veličina vektora
using namespace std;
vector < int > b={10,20,30,40,50};
cout << "Vektor ima " << b.size() << " elemenata" << endl;
Uzimanje prvog elementa iz vektora
using namespace std;
vector < int > grupa={"Mika","Pera","Laza","Nataša"};
cout << "Prvi u grupi je " << grupa.front() << endl;
Uzimanje poslednjeg elementa u vektoru
član grupe bi bio:
using namespace std;
vector < string > grupa={"Mika","Pera","Laza","Nataša"};
cout << "Poslednji u grupi je " << grupa.back() << endl;
Ubacivanje vrednosti na određenu poziciju u vektoru
auto itr=brojevi.begin() + poz;
brojevi.insert(itr, 3);
Takođe može se na određenu poziciju dodati i niz vrednosti. Npr. ako na poziciju 3 sada, želimo da umetnemo sledeći niz:
auto itr=brojevi.begin() + poz;
brojevi.insert(itr, {11, 12, 13});
Brisanje poslednjeg elementa vektora
Sledeći primer ilustruje primenu ove metode:
using namespace std;
vector < double > temperature={23.2 , 25.8 , 11, 15.3, 17};
temperature.pop_back();
Brisanje elementa vektora na određenoj poziciji
Primer:
using namespace std;
vector < int > c={2,3,4};
c.erase(c.begin() + 1);//briše element na poziciji 1 u vektoru
Brisanje svih elemenata vektora
Primer upotrebe:
using namespace std;
vector < int > c={2,3,4};
c.clear();//briše sve elemente u vektoru
Ispisivanje elemenata vektora
using namespace std;
vector < int > brojevi={1,2,3,4,5};
{
cout << endl;
Čitanje tekstualnih podataka sa standardnog ulaza i ubacivanje jednog po jednog u vektor
#include <iostream>
#include <string>
using namespace std;
// Deklarišemo vektor stringova koji će čuvati unete reči
vector<string> text;
// Promenljiva za unos pojedinačne reči
string rec;
// Učitavanje reči sa standardnog ulaza dok ih korisnik unosi
while(cin >> rec)
{
text.push_back(rec);
Prolaženje kroz elemente vektora pomoću iteratora []
for(int i = 0; i < text.size(); i++)
{
cout << endl;
Testirajte svoj kod ovde!
Prolaženje kroz elemente vektora pomoću iteratora
using namespace std;
vector < int > poeni={5,3,5,7,8,2,3,4};
cout << "Broj poena po zadacima:\n " << endl;
for(vector < int >::iterator it=poeni.begin(); it != poeni.end(); ++it)
{
cout << endl;
v.begin() – vraća iterator koji pokazuje na početni element kontejnera
v.end() – vraća iterator koji pokazuje "iza zadnjeg" elementa kontejnera.
Sortiranje vektora bibliotečnom funkcijom sort
using namespace std;
vector < int > A={4,2,7,5,9};
sort(a.begin(),a.end());
//Ispis
Važne metode std::vector
Vektori u C++ pružaju mnoge korisne metode za upravljanje dinamičkim nizovima. U nastavku su opisane osnovne metode, zajedno sa primerima koji pokazuju njihovu primenu.
Osnovne metode
Metoda | Opis |
---|---|
push_back() | Dodaje element na kraj vektora. |
pop_back() | Uklanja poslednji element iz vektora. |
size() | Vraća broj elemenata u vektoru. |
clear() | Briše sve elemente iz vektora. |
at() | Pristupa elementu na specificiranom indeksu, uz proveru granica. |
Primeri korišćenja metoda
1. Dodavanje elemenata – push_back()
Metoda push_back() koristi se za dinamičko dodavanje elemenata u vektor.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi; brojevi.push_back(10); // Dodaje 10 brojevi.push_back(20); // Dodaje 20 std::cout << brojevi[0] << ", " << brojevi[1] << "\n"; return 0; }
2. Uklanjanje elemenata – pop_back()
Metoda pop_back() uklanja poslednji element iz vektora.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {10, 20, 30}; brojevi.pop_back(); // Briše 30 std::cout << brojevi.size() << "\n"; // Ispisuje 2 return 0; }
3. Dobijanje veličine – size()
Metoda size() vraća broj elemenata u vektoru.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {1, 2, 3, 4}; std::cout << "Veličina vektora: " << brojevi.size() << "\n"; return 0; }
4. Brisanje svih elemenata – clear()
Metoda clear() uklanja sve elemente iz vektora, ostavljajući ga praznim.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {1, 2, 3}; brojevi.clear(); std::cout << "Vektor je prazan: " << brojevi.size() << "\n"; return 0; }
5. Pristup elementima – at()
Metoda at() omogućava pristup elementu sa proverom granica.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {5, 10, 15}; std::cout << brojevi.at(1) << "\n"; // Pristupa elementu na indeksu 1 return 0; }
Detaljniji primeri koda
Kako bi se bolje razumela praktična primena std::vector u C++, slede primeri koji prikazuju deklaraciju, inicijalizaciju i manipulaciju vektorima.
Deklaracija i inicijalizacija vektora
U nastavku je prikazan primer osnovne deklaracije i inicijalizacije vektora:
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {1, 2, 3, 4, 5}; for (int broj : brojevi) { std::cout << broj << " "; } return 0; }
U ovom primeru, vektor brojevi se inicijalizuje sa pet elemenata i ispisuje u petlji.
Dodavanje i uklanjanje elemenata
Vektori omogućavaju dinamičko dodavanje i uklanjanje elemenata pomoću metoda push_back i pop_back:
#include <iostream> #include <vector> int main() { std::vector<int> brojevi; brojevi.push_back(10); brojevi.push_back(20); brojevi.push_back(30); std::cout << "Vektor sadrži: "; for (int broj : brojevi) { std::cout << broj << " "; } brojevi.pop_back(); // Uklanja poslednji element std::cout << "\nNakon pop_back: "; for (int broj : brojevi) { std::cout << broj << " "; } return 0; }
Ovim pristupom možemo lako dodavati i uklanjati elemente iz vektora bez potrebe za ručnim upravljanjem memorijom.
Iteracija i pristup elementima
Možemo koristiti indeksiranje ili iterator za prolazak kroz vektor:
#include <iostream> #include <vector> int main() { std::vector<std::string> imena = {"Ana", "Marko", "Jovan"}; for (size_t i = 0; i < imena.size(); i++) { std::cout << imena[i] << " "; } std::cout << "\nKoristeći iterator: "; for (auto it = imena.begin(); it != imena.end(); ++it) { std::cout << *it << " "; } return 0; }
Ovim pristupom demonstriramo različite načine prolaska kroz vektor – klasičnim indeksom i pomoću iteratora.
Zaključak
Vektori u C++ pružaju fleksibilnu i efikasnu alternativu statičkim nizovima, nudeći dinamičku alokaciju i korisne metode za rad s podacima. Razumevanjem ovih osnovnih operacija, programeri mogu efikasno upravljati nizovima podataka u svojim aplikacijama.
Napredne funkcionalnosti
Vektori u C++ standardnoj biblioteci nude širok spektar metoda za manipulaciju podacima. Ovaj deo pokriva naprednije teme kao što su iteracija, dodavanje i uklanjanje elemenata pomoću push_back, insert i erase, kao i razliku između size i capacity.
Iteracija kroz vektor
Postoji više načina za iteraciju kroz vektor – klasičnim indeksiranjem, opsežnom petljom (range-based for loop) i korišćenjem iteratora:
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {10, 20, 30, 40, 50}; std::cout << "Klasično indeksiranje: "; for (size_t i = 0; i < brojevi.size(); i++) { std::cout << brojevi[i] << " "; } std::cout << "\nOpsežna petlja: "; for (int broj : brojevi) { std::cout << broj << " "; } std::cout << "\nIterator: "; for (auto it = brojevi.begin(); it != brojevi.end(); ++it) { std::cout << *it << " "; } return 0; }
Dodavanje i umetanje elemenata
Osim push_back, koji dodaje element na kraj vektora, možemo koristiti insert za umetanje na proizvoljnu poziciju.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {10, 20, 30}; brojevi.push_back(40); // Dodaje 40 na kraj brojevi.insert(brojevi.begin() + 1, 15); // Umeće 15 na drugu poziciju std::cout << "Vektor nakon umetanja: "; for (int broj : brojevi) { std::cout << broj << " "; } return 0; }
Brisanje elemenata
Metoda erase se koristi za uklanjanje pojedinačnih elemenata ili opsega iz vektora.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {10, 20, 30, 40, 50}; brojevi.erase(brojevi.begin() + 2); // Briše treći element (30) brojevi.erase(brojevi.begin(), brojevi.begin() + 2); // Briše prve dve vrednosti std::cout << "Vektor nakon brisanja: "; for (int broj : brojevi) { std::cout << broj << " "; } return 0; }
Razlika između size i capacity
Metoda size() vraća broj elemenata u vektoru, dok capacity() pokazuje koliko elemenata može stati u trenutno alocirani prostor.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi; std::cout << "Početni size: " << brojevi.size() << ", capacity: " << brojevi.capacity() << "\n"; brojevi.push_back(1); brojevi.push_back(2); brojevi.push_back(3); std::cout << "Nakon dodavanja size: " << brojevi.size() << ", capacity: " << brojevi.capacity() << "\n"; return 0; }
Kapacitet vektora raste dinamički kako se dodaju novi elementi, ali ne mora uvek biti jednak veličini.
Poređenje sa drugim kontejnerima
Standardna biblioteka C++ nudi više kontejnera za skladištenje podataka, od kojih su najčešće korišćeni std::vector, std::array i std::list. Svaki od njih ima specifične karakteristike koje ih čine pogodnim za određene situacije.
Poređenje ključnih osobina
Osobina | std::vector | std::array | std::list |
---|---|---|---|
Veličina | Dinamička, može da raste | Fiksna, određena pri kreiranju | Dinamička |
Brzina pristupa | O(1) – direktan pristup indeksiranjem | O(1) – direktan pristup indeksiranjem | O(n) – mora se preći lista do traženog elementa |
Dodavanje/brisanje elemenata | Efikasno na kraju (O(1)), sporo na početku i u sredini (O(n)) | Nije moguće (fiksna veličina) | Efikasno bilo gde (O(1)), ali bez direktnog pristupa |
Interna struktura | Niz u memoriji, elementi su smešteni uzastopno | Staticki niz, elementi su smešteni uzastopno | Povezana lista, svaki element sadrži pokazivače na sledeći/prethodni |
Kada koristiti koji kontejner?
- std::vector: Kada su potrebne dinamičke veličine i brz pristup indeksiranjem.
- std::array: Kada se zna fiksna veličina niza i potrebne su male režijske troškove.
- std::list: Kada se često dodaju ili uklanjaju elementi sa početka/sredine strukture.
Praktični primeri
1. Korišćenje std::vector
std::vector je odličan kada treba dinamički dodavati elemente.
#include <iostream>
#include <vector>
int main() {
std::vector<int> brojevi = {1, 2, 3};
brojevi.push_back(4); // Dodaje element na kraj
std::cout << "Treći element: " << brojevi[2] << "\n"; // O(1) pristup
return 0;
}
2. Korišćenje std::array
std::array je statički niz koji koristi stack memoriju, što ga čini bržim kada je poznata veličina.
#include <iostream>
#include <array>
int main() {
std::array<int, 3> brojevi = {10, 20, 30};
std::cout << "Prvi element: " << brojevi[0] << "\n"; // O(1) pristup
return 0;
}
3. Korišćenje std::list
std::list je korisna kada je potrebno često umetanje ili brisanje sa bilo koje pozicije.
#include <iostream>
#include <list>
int main() {
std::list<int> brojevi = {10, 20, 30};
brojevi.push_front(5); // Dodaje 5 na početak
brojevi.erase(brojevi.begin()); // Briše prvi element
std::cout << "Prvi element nakon brisanja: " << *brojevi.begin() << "\n";
return 0;
}
Zaključak
Izbor između std::vector, std::array i std::list zavisi od potreba programa. Ako vam je potreban brz pristup elementima i mogućnost dinamičkog rasta, std::vector je najbolji izbor. Ako vam treba fiksna veličina bez dodatnih troškova memorije, koristite std::array. Ako često dodajete i brišete elemente sa različitih pozicija, std::list je bolja opcija.
Diskusija o efikasnosti i upotrebi
Vektori u C++ imaju mnoge prednosti u poređenju sa statičkim nizovima, posebno kada je u pitanju rad sa dinamičkim podacima. Međutim, njihova upotreba dolazi sa određenim kompromisima. U nastavku su objašnjene prednosti i potencijalni nedostaci vektora, zajedno sa primerima za bolje razumevanje.
Prednosti vektora
Osobina | Opis |
---|---|
Dinamička veličina | Vektori automatski prilagođavaju veličinu u zavisnosti od broja elemenata, za razliku od statičkih nizova sa fiksnom veličinom. |
Lakoća upotrebe | Vektori dolaze sa ugrađenim metodama za dodavanje, uklanjanje i pretraživanje elemenata. |
Bezbednost | Metode poput at() omogućavaju proveru granica, čime se izbegava pristup nepostojećim elementima. |
Primer: Dinamičko proširenje
Jedna od najvećih prednosti vektora je automatsko proširenje, koje omogućava rad sa nepoznatim brojem elemenata tokom izvršavanja programa.
#include <iostream>
#include <vector>
int main() {
std::vector<int> brojevi;
for (int i = 1; i <= 10; ++i) {
brojevi.push_back(i); // Dinamički dodaje brojeve od 1 do 10
}
for (int broj : brojevi) {
std::cout << " " << broj << " ";
}
return 0;
}
Nedostaci vektora
Osobina | Opis |
---|---|
Prealokacija memorije | Vektori alociraju dodatnu memoriju kako bi smanjili učestalost realokacije, što može dovesti do neefikasnog korišćenja memorije. |
Performanse | Kada se vektor širi, potrebna je realokacija elemenata, što može biti skupo u smislu vremena izvršavanja. |
Primer: Efekat realokacije
Kada se vektor širi, alocira se nova memorija, a postojeći elementi se kopiraju na novu lokaciju. Ovo može uzrokovati pad performansi kod intenzivnog dodavanja elemenata.
#include <iostream>
#include <vector>
int main() {
std::vector<int> brojevi;
for (int i = 1; i <= 100000; ++i) {
brojevi.push_back(i); // Često širenje zbog dodavanja elemenata
}
std::cout << "Ukupan broj elemenata: " << brojevi.size() << "\n";
return 0;
}
Zaključak
Vektori su idealni za scenarije gde je veličina podataka promenljiva, jer olakšavaju rad sa dinamičkim strukturama. Međutim, treba voditi računa o njihovim ograničenjima, poput potencijalne neefikasnosti u korišćenju memorije i performansi u slučajevima čestih proširenja. U takvim situacijama, možda je bolje razmotriti druge strukture podataka, poput std::deque ili std::list.
Napredne teme
Pored osnovnih operacija, vektori u C++ omogućavaju rad sa naprednijim konceptima kao što su iteratori, razlika između kapaciteta i veličine, i rad sa 2D vektorima (vektori vektora). Ove teme su ključne za napredno rukovanje dinamičkim strukturama podataka u složenijim scenarijima.
1. Iteratori za prolazak kroz vektor
Iteratori omogućavaju fleksibilan i efikasan prolazak kroz elemente vektora, čime se pruža kontrola nad elementima bez direktnog korišćenja indeksa.
#include <iostream>
#include <vector>
int main() {
std::vector<int> brojevi = {1, 2, 3, 4, 5};
for (std::vector<int>::iterator it = brojevi.begin(); it != brojevi.end(); ++it) {
std::cout << "Element: " << *it << "\n";
}
return 0;
}
Iteratori se koriste pomoću funkcija poput begin() i end(), pri čemu *it
pristupa vrednosti na trenutnoj poziciji iteratora.
2. Razlika između kapaciteta i veličine
Veličina (size()) predstavlja trenutni broj elemenata u vektoru, dok kapacitet (capacity()) pokazuje koliko elemenata vektor može da sadrži pre nego što se izvrši realokacija memorije.
#include <iostream>
#include <vector>
int main() {
std::vector<int> brojevi;
brojevi.push_back(10);
brojevi.push_back(20);
std::cout << "Veličina: "
<< brojevi.size()
<< ", Kapacitet: "
<< brojevi.capacity()
<< "\n";
brojevi.reserve(100); // Rezerviše prostor za 100 elemenata
std::cout << "Kapacitet nakon reserve: "
<< brojevi.capacity()
<< "\n";
return 0;
}
Rezervacija kapaciteta unapred može poboljšati performanse kada se očekuje veliki broj dodatnih elemenata.
3. Rad sa 2D vektorima (vektori vektora)
Vektori vektora omogućavaju rad sa matricama ili tabelarnim podacima. Svaki element glavnog vektora može biti vektor, čime se kreira struktura slična 2D nizu.
#include <iostream>
#include <vector>
int main() {
std::vector<std::vector<int>> matrica = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
std::cout << "Element [0][1]: "
<< matrica[0][1]
<< "\n";
for (int i = 0; i < matrica.size(); ++i) {
for (int j = 0; j < matrica[i].size(); ++j) {
std::cout << matrica[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Vektori vektora su fleksibilniji od klasičnih 2D nizova, jer svaka "reda" može imati različit broj kolona.
Zaključak
Ove napredne teme pružaju značajnu fleksibilnost u radu sa podacima u C++. Razumevanje iteratora, razlike između kapaciteta i veličine, kao i rad sa višedimenzionalnim strukturama omogućava efikasno korišćenje vektora u složenijim scenarijima.
Praktični zadaci
Da bi se bolje razumelo korišćenje vektora u C++, predlažemo nekoliko jednostavnih zadataka za vežbu. Ovi zadaci obuhvataju unos i obradu elemenata vektora, kao i primenu osnovnih metoda i petlji.
1. Unos n brojeva i njihovo ispisivanje obrnutim redosledom
Zadatak: Omogućiti korisniku da unese n brojeva u vektor i zatim ispisati te brojeve obrnutim redosledom.
#include <iostream> #include <vector> int main() { int n; std::cout << "Unesite broj elemenata: "; std::cin >> n; std::vector<int> brojevi(n); for (int i = 0; i < n; ++i) { std::cout << "Unesite broj " << i + 1 << ": "; std::cin >> brojevi[i]; } std::cout << "Brojevi obrnutim redosledom:\n"; for (int i = n - 1; i >= 0; --i) { std::cout << brojevi[i] << " "; } std::cout << "\n"; return 0; }
2. Filtriranje parnih brojeva iz vektora
Zadatak: Uneti niz brojeva i iz njega izdvojiti sve parne brojeve u novi vektor.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<int> parni; for (int broj : brojevi) { if (broj % 2 == 0) { parni.push_back(broj); } } std::cout << "Parni brojevi:\n"; for (int broj : parni) { std::cout << broj << " "; } std::cout << "\n"; return 0; }
3. Računanje proseka elemenata
Zadatak: Uneti niz brojeva i izračunati njihov prosek.
#include <iostream> #include <vector> int main() { std::vector<int> brojevi = {10, 20, 30, 40, 50}; int suma = 0; for (int broj : brojevi) { suma += broj; } double prosek = (double)suma / brojevi.size(); std::cout << "Prosek: " << prosek << "\n"; return 0; }
Zaključak
Ovi zadaci pružaju praktične primere za razumevanje osnovnih operacija sa vektorima, kao što su unos, filtriranje i agregacija. Preporučuje se da se zadaci dodatno prošire radi vežbe, na primer dodavanjem provere unosa ili rada sa većim skupovima podataka.
Dodavanje resursa
Kako biste dodatno proširili svoje znanje o vektorima i njihovoj upotrebi u C++, preporučujemo sledeće resurse. Ovi materijali pokrivaju osnovne i napredne teme, pružajući teorijske osnove i praktične primere.
1. Zvanična dokumentacija
Zvanična dokumentacija C++ standardne biblioteke pruža detaljne informacije o svim funkcijama i metodama vektora, kao i primere njihove upotrebe. Preporučuje se za precizne i pouzdane informacije.
2. Online kursevi
Ako više volite interaktivni pristup učenju, sledeći online kursevi pružaju detaljne lekcije o radu sa vektorima i drugim konceptima u C++:
- Udemy: Beginning C++ Programming - From Beginner to Beyond
- Coursera: Programming in C++
- Pluralsight: C++ Fundamentals
3. Relevantne knjige
Knjige o C++ programiranju često uključuju opširne informacije o vektorima. Evo nekoliko preporučenih naslova za različite nivoe znanja:
- "The C++ Programming Language" - Bjarne Stroustrup (autor jezika C++)
- "Effective Modern C++" - Scott Meyers (odličan vodič za savremeni C++)
- "C++ Primer" - Stanley B. Lippman, Josée Lajoie, Barbara E. Moo (sjajna knjiga za početnike i srednji nivo)
4. Vodiči i tutorijali
Sledeći tutorijali i vodiči pružaju praktična uputstva i primere:
5. Diskusije i zajednice
Učešće u zajednicama i forumima može vam pomoći da rešite specifične probleme i učite od drugih. Preporučene zajednice:
Zaključak
Učenje kroz različite resurse pruža širok spektar znanja i pomaže u razumevanju kako se vektori koriste u stvarnim projektima. Preporučuje se kombinacija teorije, praktičnih vežbi i konsultacija sa zajednicama radi sveobuhvatnog savladavanja ove teme.
Sledeće
Rečnik podataka-mape u C++ >| |