Vector Functions :
vector rbegin() and rend()
vector::cbegin() and vector::cend()
vector::crend() and vector::crbegin()
vector::assign()
vector::at()
vector::back()
vector::capacity()
vector::clear()
vector::push_back()
vector::pop_back()
vector::empty()
vector::erase()
vector::size()
vector::swap()
vector::reserve()
vector::resize()
vector::shrink_to_fit()
vector::operator=
vector::operator[]
vector::front()
vector::data()
vector::emplace_back()
vector::emplace()
vector::max_size()
vector::insert()
Стандардната библиотека на шаблони (STL - Standard Template Library) претставува множество од структури и алгоритми кои може да вршат операции над различни типови на податоци. Да разгледаме еден едноставен пример на програма која создава листа од 10 цели броеви, ја подредува истата во растечки редослед и потоа ја печати на екран:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector< int > v; for ( int i=1; i<=10; i++) v.push_back((i*i*i) % 20); //v={1, 8, 7, 4, 5, 16, 3, 12, 9, 0} //podredi gi broevite sort(v.begin(), v.end()); for ( int i=0; i<v.size(); i++) cout << v[i] << " " ; //pechati "0 1 3 4 5 7 8 9 12 16 " return 0; } |
Да започнеме со објаснување на составните делови на Стандардната библиотека на шаблони: контејнерите, итераторите и алгоритмите .
Контејнерите претставуваат структури на податоци во кои може да се чуваат разни информации. Досега, зборувавме за само еден симплифициран "контејнер" на податоци: низата. Всушност, во целиот програмски јазик C++ (без STL), не постои друг контејнер во кој може да се сместуваат повеќе податоци од еден ист тип. Во примерот даден погоре, вектор (vector) претставува контејнер за чување на податоци од тип int (vector<int>). Сите контејнери кои се дел од Стандардната библиотека на шаблони се имплементирани како параметаризирани структури. Ова значи дека еден контејнер може да служи за чување на податоци од кој било тип (int, float, double, string, vector<int>, vector<float>, vector<vector<float> >, итн). За да може да користиме контејнер, потребно е да ја вклучиме датотеката во која е тој дефиниран - наредба #include <vector>.
Итераторите претставуваат еден вид покажувачи кон елементите од контејнерите. Итераторите се користат за движење низ елементите од еден контејнер, како и за означување на делови од податоци врз кои сакаме да вршиме операции. Во програмата дадена погоре, како параметри на функцијата sort испративме два итератора: v.begin() и v.end(). Овие итератори означуваат дека сакаме да ги подредиме сите елементи од векторот v - сите елементи помеѓу v.begin() и v.end().
Алгоритмите служат за вршење на операции врз податоци (подредување, пронаоѓање на најголема вредност, итн.). Во програмата дадена погоре, извршивме операција подредување врз сите податоци помеѓу v.begin() и v.end(). Ова го направивме со повикување на функцијата sort(pocetok, kraj). И тука, повторно, забележете дека е потребно вклучување на соодветната датотека во која е дефинирана функцијата за подредување (#include <algorithm>)
Вектор
Векторот (vector) е наједноставниот контејнер од Стандардната библиотека на шаблони. Векторот всушност претставува низа чија големина се определува динамички, т.е. за време на извршување на програмата (еден вид "паметна" низа). Дополнително, за разлика од низите, векторот нуди едноставни методи (функции) преку кои може да се одреди или промени неговата големина, да се додаде или избрише одреден елемент, итн.
Следнава програма креира празен вектор, додава неколку елементи (од тип string) во векторот и, на крај, ја печати неговата содржина.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> #include <vector> #include <string> using namespace std; int main() { vector<string> zborovi; zborovi.push_back( "zdravo" ); zborovi.push_back( "pero" ); zborovi.push_back( "kako" ); zborovi.push_back( "si" ); for ( int i=0; i<zborovi.size(); i++) cout << zborovi[i] << " " ; //pechati "zdravo pero kako si " return 0; } |
До елементите на векторот пристапуваме на идентичен начин како што пристапуваме и до елементите на една низа - со користење на операторот [p]. Како што може да забележите од програмата дадена погоре, елементи во векторот додаваме со повик на методот push_back(string str). На тој начин, ја зголемуваме големината на векторот за 1. Векторот ја одредува потребната меморија автоматски, па не се грижете за перформансите на операцијата за додавање на нов елемент. Всушност, за да може да додаваме елементи во векторот во константно O(1) време, кога се додаваат одредени елементи, векторот врши алоцирање на повеќе меморија отколку што е тоа потребно во тој момент. Со методот capacity() може да одредиме за колку точно елементи е резервирано меморија - односно колку елементи може да се сместат во векторот пред неговата големина да биде (автоматски) зголемена.
Бројот на елементи во векторот може да се открие со повик на методот size(). Важно е да знаете дека size() враќа целобројни типови на податоци (што е нормално), но податоци кои се без знак (unsigned). Поради тоа, кога ја преведуваме програмата дадена погоре, компајлерот ќе не предупреди дека споредуваме (i < zborovi.size()) два различни целобројни типови на податоци (едниот со знак - i, а другиот без знак). Поради тоа, потребно е или да го промениме типот на променливата i, или да извршиме кастирање (претопување) на податокот кој ќе го врати методот size() - на пример, i < (int) zborovi.size(). Кај сите примери кои ќе бидат дадени во продолжение, ќе биде извршено претопување (во тип int) на податокот кој го враќа методот size().
Големината на векторот (бројот на елементи) може да ја специфицираме и при неговото креирање - со наведување на бројот на елементи и нивната иницијална вредност: по името на променливата, во загради. Покрај ова, за време на извршување на програмата, со повикување на методот resize може да го зголемиме или намалиме бројот на елементи во векторот. Доколку, како аргумент на resize, пратиме вредност која е поголема од тековниот број на елементи, тогаш на крајот од векторот ќе се додадат нови елементи. Во спротивно, доколку како аргумент испратиме вредност која е помала од тековниот број на елементи, тогаш од векторот ќе се избришат последните неколку елементи. Можеме да ги избришеме сите елементи од векторот (да ја поставиме неговата големина на 0) со повикување на методот clear().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <iostream> #include <vector> using namespace std; int main() { vector< int > v0; //v={} vector< int > v1(5, 0); //v1={0, 0, 0, 0, 0} vector< int > v2(3, 5); //v2={5, 5, 5} //ako ne navedeme vtor argument, se pretpostavuva 0 vector< int > v3(3); //v3={0, 0, 0} vector< int > v4(v2); //v4={5, 5, 5} //v1.resize(n, v) -> [n] oznacuva kolku elementi, a [v] koja vrednost //treba da se iskoristi dokolku treba da se dodadat novi elementi v1.resize(7, 3); //v1={0, 0, 0, 0, 0, 3, 3} v1.push_back(2); / /v1={0, 0, 0, 0, 0, 3, 3, 2} v1.resize(2, 5); //v1={0, 0} v1.resize(2, 8); //v1={0, 0} v1.push_back(5); //v1={0, 0, 5} v1.resize(4, 3); //v1={0, 0, 5, 3} v1.resize(5); //v1={0, 0, 5, 3, 0} v1.clear(); //v1={} v2.clear(); //v2={} cout << v1.size() + v2.size() << endl; //pechati '0' return 0; } |
Два вектори може да се споредат со примена на операторите == и != (на пример, v1 == v2). Притоа, споредувањето се врши елемент по елемент.
Дозволено е и креирање на повеќедимензионални низи. Притоа, треба да се внимава да се остави празно место помеѓу двата знака '>' на крајот од дефиницијата на еден вектор. Ова треба да се направи бидејќи, во C++, веќе постои оператор '>>' (кој, како што веќе знаете, служи за поместување на битови).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <iostream> #include <vector> using namespace std; int main() { //edna dimenzija vector<string> v1(3, "ABC" ); //v1={"ABC", "ABC", "ABC"); //dve dimenzii (zabelezhete '> >') vector<vector< int > > v2(3); //v2={{}, {}, {}) v2[0].push_back(1); //v2={{1}, {}, {}) v2[0].push_back(2); //v2={{1, 2}, {}, {}) v2[1].push_back(3); //v2={{1, 2}, {3}, {}) v2[2].push_back(4); //v2={{1, 2}, {3}, {4}) v2[2].push_back(5); //v2={{1, 2}, {3}, {4, 5}) v2[2].push_back(6); //v2={{1, 2}, {3}, {4, 5, 6}) cout << v2[0][0] + v2[0][1] << endl; //pechati '3' (1+2) cout << v2[1][0] << endl; //pechati '3' (3) cout << v2[2][0] + v2[2][1] + v2[2][2] << endl; //pechati '15' (4+5+6) cout << v2[0].size() << endl; //pechati '2' cout << v2[1].size() << endl; //pechati '1' cout << v2[2].size() << endl; //pechati '3' return 0; } |
Постојат и методи (insert и erase) кои служат за вметнување на елемент (или елементи) на произволна позиција во векторот (не само на крајот, како што го прави тоа push_back), односно бришење на произволен елемент (или елементи) од векторот. Овие операции имаат линеарна сложеност: за додавање или бришење на елемент е потребно поместување на сите елементи кои се наоѓаат по тој елемент - на десно, доколку се додава нов елемент, или на лево, доколку се брише одреден елемент.
Следната програма го илустрира ефектот од методите кои не беа искористени во претходните програми:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <iostream> #include <vector> using namespace std; int main() { vector< int > v; //v={} v.push_back(3); //v={3} v.push_back(1); //v={3, 1} v.push_back(5); //v={3, 1, 5} v.pop_back(); //v={3, 1} - brishenje na posledniot element v.front() = 1; //v={1, 1} - promena na prviot element v.back() = 7; //v={1, 7} - promena na posledniot element cout << v.front() + v.back() << endl; //pechati '8' (1+7) if (v.empty() == false ) cout << v.size() << endl; //pechati '2' v.insert(v.begin(), 9); //v={9, 1, 7} v.insert(v.begin(), 3, 2); //v={2, 2, 2, 9, 1, 7} v.erase(v.begin()); //v={2, 2, 9, 1, 7} cout << v.size() << endl; //pechati '5' return 0; } |
Итератори
Итераторите овозможуваат движење низ елементите од еден контејнер, но и означување на групи податоци врз кои сакаме да вршиме одредени операции. Итераторите (интересно) нудат слични можности како и покажувачите: движење нанапред или наназад со помош на операторите ++ и --, скокање нанапред или наназад со одреден чекор (v.begin() + 20, v.end() - 4), добивање на вредноста кон која покажува итераторот (*it), споредување со други итератори (!=, ==, <, <=, >, >=) и одредување на растојанието (во број на елементи) помеѓу два итератори (користејќи го изразот it1 - it2, или преку повикување на методот distance).
Забележете дека, поради фактот што итераторите нудат слични операции како покажувачите, во C++ е овозможено користење на алгоритмите кои се дел од Стандардната библиотека на шаблони врз низи од податоци.
Да разгледаме еден пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector< int > v; for ( int i=0; i<10; i++) v.push_back((i*i*i) % 10); //v={0, 1, 8, 7, 4, 5, 6, 3, 2, 9} sort(v.begin(), v.end()); //v={0, 1, 2, 3, 4, 5, 6, 7, 8, 9} //vrz nizi int array[10]; for ( int i=0; i<10; i++) array[i] = (i*i*i) % 10; //array={0, 1, 8, 7, 4, 5, 6, 3, 2, 9} sort(array, array+10); //array={0, 1, 2, 3, 4, 5, 6, 7, 8, 9} vector< int >::iterator it = v.begin(); cout << *it << endl; //pechati '0' it++; cout << *it << endl; //pechati '1' *it = 7; //v={0, 7, 2, 3, 4, 5, 6, 7, 8, 9} cout << *it << endl; //pechati '7' it += 2; cout << *it << endl; //pechati '3' //izminuvanje na site elementi it = v.begin(); while (it != v.end()) { cout << *it << endl; it++; } cout << distance(v.begin(), v.end()) << endl; //pechati '10' return 0; } |
Забележете дека итераторот begin() покажува на првиот елемент на еден контејнер (заменето со array - што е локацијата на првиот елемент на низата array). Од друга страна, итераторот end() не покажува на последниот елемент!!! од контејнерот, туку на еден елемент после него (заменето со array + 10 - локацијата на array[10]). На овој начин, можеме ефикасно да ги изминеме сите елементи од еден контејнер - се движиме низ елементите се додека не биде исполнет условот it == container.end(). Сите контејнери и алгоритми кои се дел од Стандардната библиотека на шаблони го користат овој факт - при повикување на која било функција која очекува опсег на елементи (почетен и краен итератор), се вршат операции од почетниот итератор (вклучувајќи го и елементот на кој тој покажува) до крајниот итератор (но, не вклучувајќи го елементот на кој тој покажува).
Всушност, во претходната програма, елементите v[10] и array[10] не ни постојат, и пристапувањето до нивната вредност би било грешка.
Векторите во C ++ се динамички низи што се користат за складирање на податоци. За разлика од низите, кои се користат за складирање на последователни податоци и имаат статична природа, векторите обезбедуваат поголема флексибилност на програмата - можат автоматски да ја менуваат големината кога некој елемент се вметнува или брише.
Синтакса
vector< object_type > variable_name;
Задолжително е да се одреди типот и името на променливата. Пример vector <int > a;cout << "Prv vo grupata e " << grupa.front() << endl;
cout << "Posleden vo grupata e " << grupa.back() << endl;
temperature.pop_back();
ime_na_ vector .erase - бришење на елемент на одредена позиција во векторот
vector < int > c={2,3,4};c.erase(c.begin() + 1); //go brise elementot na pozicija 1 vo vektorot
ime_na_ vector .clear - бришење на сите елементи
vector < int > c={2,3,4};c.clear();//brisenje na site elementi vo vektorot, posle ova toj e prazen
Печатење на елементите на вектор
using namespace std;
vector < int > broevi={1,2,3,4,5};
{
cout << endl;}
Output: 1 2 3 4 5
Iterators An iterator allows you to access the data elements stored within the C++ vector. It is an object that functions as a pointer.
- begin() –Returns an iterator pointing to the first element in the vector
end() – Returns an iterator pointing to the theoretical element that follows the last element in the vector
rbegin() – Returns a reverse iterator pointing to the last element in the vector (reverse beginning). It moves from last to first element
rend() – Returns a reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reverse end)
cbegin() – Returns a constant iterator pointing to the first element in the vector.
cend() – Returns a constant iterator pointing to the theoretical element that follows the last element in the vector.
crbegin() – Returns a constant reverse iterator pointing to the last element in the vector (reverse beginning). It moves from last to first element
crend() – Returns a constant reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reverse end)
#include <iostream> #include <vector> using namespace std; int main() { vector< int > vec1; for ( int i = 1 ; i <= 10 ; i++) vec1.push_back(i); cout << "Understanding begin() and end() function: " << endl; // for (auto i = vec1.begin(); i != vec1.end(); ++i) // cout << *i << " " ; for ( int i = 0; i < vec1.size(); ++i)
cout << vec1 [i]; return 0 ; } |
Capacity
size() – Returns the number of elements in the vector.max_size() – Returns the maximum number of elements that the vector can hold.
capacity() – Returns the size of the storage space currently allocated to the vector expressed as number of elements.
resize(n) – Resizes the container so that it contains ‘n’ elements.
empty() – Returns whether the container is empty.
shrink_to_fit() – Reduces the capacity of the container to fit its size and destroys all elements beyond the capacity.
reserve() – Requests that the vector capacity be at least enough to contain n elements.
#include <iostream> #include <vector> using namespace std; int main() { vector< int > vec1; for ( int i = 1 ; i <= 10 ; i++) vec1.push_back(i); cout << "Size of our vector: " << vec1.size(); cout << "\nCapacity of our vector: " << vec1.capacity(); cout << "\nMax_Size of our vector: " << vec1.max_size(); // resizes the vector size to 4 vec1.resize( 4 ); // prints the vector size after resize() cout << "\nSize of our vector after resize: " << vec1.size(); // checks if the vector is empty or not if (vec1.empty() == false ) cout << "\nVector is not empty" ; else cout << "\nVector is empty" ; return 0 ; } |
Output: ????
// resizing of the vector#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
// 5 elements are inserted in the vector
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
cout << "Contents of vector before resizing:" << endl;
// displaying the contents of the vector before resizing
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
// vector is resized
vec.resize(4);
cout << "Contents of vector after resizing:" << endl;
// displaying the contents of the vector after resizing
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
return 0;
}
Modifiers:
- assign() – It assigns new value to the vector elements by replacing old ones
push_back() – It push the elements into a vector from the back
pop_back() – It is used to pop or remove elements from a vector from the back.
insert() – It inserts new elements before the element at the specified position
erase() – It is used to remove elements from a container from the specified position or range.
swap() – It is used to swap the contents of one vector with another vector of same type. Sizes may differ.
clear() – It is used to remove all the elements of the vector container
emplace() – It extends the container by inserting new element at position
emplace_back() – It is used to insert a new element into the vector container, the new element is added to the end of the vector
// Modifiers in vector #include <iostream> //#include <bits/stdc++.h> #include <vector> using namespace std; int main() { // Assign vector vector< int > vec; // fill the array with 12 seven times vec.assign( 7 , 12 ); cout << "The vector elements are: " ; for ( int i = 0 ; i < 7 ; i++) cout << vec[i] << " " ; // inserts 24 to the last position vec.push_back( 24 ); int s = vec.size(); cout << "\nThe last element is: " << vec[s - 1 ]; // prints the vector cout << "\nThe vector elements after push back are: " ; for ( int i = 0 ; i < vec.size(); i++) cout << vec[i] << " " ; // removes last element vec.pop_back(); // prints the vector cout << "\nThe vector elements after pop_back are: " ; for ( int i = 0 ; i < vec.size(); i++) cout << vec[i] << " " ; // inserts 10 at the beginning vec.insert(vec.begin(), 10 ); cout << "\nThe first element after insert command is: " << vec[ 0 ]; // removes the first element vec.erase(vec.begin()); cout << "\nThe first element after erase command is: " << vec[ 0 ]; // inserts at the beginning vec.emplace(vec.begin(), 5 ); cout << "\nThe first element emplace is: " << vec[ 0 ]; // Inserts 20 at the end vec.emplace_back( 20 ); s = vec.size(); cout << "\nThe last element after emplace_back is: " << vec[s - 1 ]; // erases the vector vec.clear(); cout << "\nVector size after clear(): " << vec.size(); // two vector to perform swap vector< int > obj1, obj2; obj1.push_back( 2 ); obj1.push_back( 4 ); obj2.push_back( 6 ); obj2.push_back( 8 ); cout << "\n\nVector 1: " ; for ( int i = 0 ; i < obj1.size(); i++) cout << obj1[i] << " " ; cout << "\nVector 2: " ; for ( int i = 0 ; i < obj2.size(); i++) cout << obj2[i] << " " ; // Swaps obj1 and obj2 obj1.swap(obj2); cout << "\nAfter Swap nVector 1: " ; for ( int i = 0 ; i < obj1.size(); i++) cout << obj1[i] << " " ; cout << "\nVector 2: " ; for ( int i = 0 ; i < obj2.size(); i++) cout << obj2[i] << " " ; } |
Output:
No comments:
Post a Comment