Vector in C++ Stl
Introduction
In simple terms, a vector belongs to the category of data structures called dynamic arrays. The size of the vector may be altered as it is being executed, which is different from a more conventional array. The vectors have a dynamic structure as a result of this.
Thus, vectors are most useful when it comes to storing items and allowing them to change in size over time. Vectors, like strings or integers, constantly have the same element in them; hence, this should be remembered.
Because their elements are stored consecutively, vectors also benefit from being traversable using iterators.
How do we use vectors?
#include<vector>
#include <iostream>
int main() {
std::vector<int> fact {3,5,6,7,8};
for(int i : vect){
std::cout << i<< " ";
}
std::cout <<std::endl;
return 0;
}
![Vector in C++ Stl](https://static.tutorialandexample.com/cpp/vector-in-cpp-stl1.png)
Explanation
The "vector" header file, where vectors are specified, must be included if you want to use them. Next, You should declare a variable and specify the data type for the elements you'd like to include within your vector. For example, in the following sentence,
std::vector<int> number;
"std" stands for the STL, "int" represents the vector's type (an integer), and a "number stands for the vector's name.
How can vectors in C++ STL be used?
These include the object types that are utilized to navigate through the vector's elements. Iterators are like pointers in that they can be used to acquire the numerical value of the element they point at and increment and decrement it. The different kinds of iterators are:
- begin (): gives a pointer to the initial vector element in the format of an iterator.
- end (): The element that should logically proceed from the final vector item is indicated by the given iterator in this function.
- rbegin (): The resulting iterator, which has a reversed start, refers to the last element instead of the first.
- rend(). The theoretical element before the first item is indicated by the iterator in this call to rend().
- cbegin() and send (): Similarly to begin() and end(), begin () and send () utilize a constant iterator that is unable to alter the value that it's pointing at.
- rbegin() and rend(): Similar to rbegin() and rend(), although using a constant iterator instead.
Each type of iterator that may be utilized with vectors is demonstrated in the code that follows.
Example:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec{6,7,8,9,3}
for (std::size_t i = 0; i < vec.size(); i++){
std::cout << vec[i] << " ";
}
std::cout << std::endl;
for (auto it = vec.begin(); it != vec.end(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
const std::vector<int> const_vec{4,6,7,8,9};
for (auto it = const_vec.cbegin(); it != const_vec.cend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
for (auto it = vec.rbegin(); it != vec.rend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
for (auto it = const_vec.crbegin(); it != const_vec.crend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;}
Output
![Vector in C++ Stl](https://static.tutorialandexample.com/cpp/vector-in-cpp-stl2.png)
Explanation
For iteration through the vector "vec," we are utilizing for loops in this case. We establish an additional vector called "const_vec" for the constant iterators.
Capacity Functions
There are almost countless functions that may be employed with vectors, but the assessment and alteration of a vector's size are some of the most frequently used. Following is a description of functions related to capacity:
- size(): The vector's size, or the amount of each of its elements, is returned by the size() function.
- max_size(): Utilizing the function max_size(), you can find out how many elements a single vector can carry in total.
- resize(n): The vector of data is resized to have "n" elements with the function resize(n).
- capacity(): Using the capacity() operation, you can find out how many elements a vector can hold without using more memory.
- empty (): Determine if a vector is empty or not using the empty() function.
- shrink_to_fit(): shrink_to_fit() reduces the vector's ability to fit just the current elements.
- reverse(): The function reserve() "reserves" spaces in a vector for a specified number of entries.
In the same manner that we did previously, we've added an example to show how to use these functions.
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> vect;
std::cout << "Initial size of vector: " << vect.size() << std::endl;
std::cout << "Max size of vector: " << vect.max_size() << std::endl;
vect.reserve(9);
std::cout << "Capacity of vec after reserving 10 elements: " << vect.capacity() << std::endl;
for (int i = 0; i < 6; i++) {
vect.push_back(i);
}
std::cout << "Size of vec after adding 5 elements: " << vect.size() << std::endl;
vect.resize(9);
std::cout << "Size of vec after resizing to 10 elements: " << vect.size() << std::endl;
if (vect.empty()) {
std::cout << "Vector is empty." << std::endl;
} else {
std::cout << "Vector is not empty." << std::endl;
}
vect.shrink_to_fit();
std::cout << "Capacity of vec after shrinking to fit its size: " << vect.capacity() << std::endl;
return 0;
}
Output
![Vector in C++ Stl](https://static.tutorialandexample.com/cpp/vector-in-cpp-stl3.png)
Explanation
The starting and maximum sizes of the vector "vec" have been printed after initializing it. Then, nine elements' amounts of space are set aside, and five of them are added. The resulting vector is then scaled down to a minimum of nine elements, confirmed to ensure it isn't empty, and then reduced to fit. As seen in the image, the results are printed at every step.
Accessing Elements
The ability to modify every element of a vector is just as important as having access to its elements. The following are the functions used to access elements:
- operator (): It establishes a connection with the component at the given vector index.
- at(): With the possible exception of giving, at() always accesses an element at a given index. A "std::out_of_range" exception occurs if the value of the index is outside of range.
- front (): The function that provides a pointer for the topmost vector element.
- data (): It provides a link to the first element.
The code below can be used to demonstrate these functionalities.
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {4,5,6,7,8};
std::cout << "Element at index 2: " << vec[2] << std::endl;
try {
std::cout << "Element at index 6: " << vec.at(6) << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Out of range exception: " << e.what() << std::endl;
}
std::cout << "First element: " << vec.front() << std::endl;
std::cout << "Last element: " << vec.back() << std::endl;
int* ptr = vec.data();
std::cout << "Elements in vector: ";
for (std::size_t i = 0; i < vec.size(); ++i) {
std::cout << *(ptr + i) << " "
}
std::cout << std::endl;
return 0;
}
Output
![Vector in C++ Stl](https://static.tutorialandexample.com/cpp/vector-in-cpp-stl4.png)
Explanation
Initializing the vector "vec" with 6 elements is the initial step. Using operator(), the following element is accessed. The at() method now tries to access the sixth element, but it doesn't exist. Thus, a try-catch sequence is used to print an error message.
After using front() and back() to get the first and last elements, accordingly, the data() method gradually refers to every element, and then all the outcomes are printed. The image above shows the results.
Modifying Elements
It is time to demonstrate how to edit the vector's contents now that you've learned how to get to your vector elements, measure the vector's capacity, and navigate the vector. Following are some of the functions that are utilized to change the elements:
Assign () In place of the previous values, and the assign() function assigns new values to vector members.
- push_back() The function push_back() "pushes" the concerned elements to the vector's rear.
- pop_back(): This approach eliminates components from the back rather than adding more.
- insert (): Elements are put in before the one that is supplied.
- erase(): Erases all elements at the provided location.
- clear () eliminates every component of the vector.
- swap (): Swaps the elements of every vector that is supplied.
- emplace (): instead of simply copying the value to the vector, a vector is expanded by adding an element at the provided location.
- emback(): Similarly, to emplace(), emback() adds an element to the vector's back.
- Have a look at the next code that demonstrates these features:
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec {1, 2, 3};
vec.assign({4, 5, 6});
vec.push_back(7);
vec.pop_back();
vec.insert(vec.begin() + 1, 8);
vec.erase(vec.begin() + 1);
std::vector<int> vec2 {10, 20, 30};
vec.swap(vec2);
vec.clear();
vec.emplace(vec.begin(), 9);
vec.emplace_back(11);
std::cout << "vec: ";
for (int i : vec) {
std::cout << i << " ";
}
std::cout << "\nvec2: ";
for (int i : vec2) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
Output
![Vector in C++ Stl](https://static.tutorialandexample.com/cpp/vector-in-cpp-stl5.png)
Code Explanation
Generating the vector "vec" with the values 1, 2, and 3 is the first step. Consequently, we utilize Assign() to modify the given numbers to 4, 5, and 6. The resulting vector now has the values 4, 5, 6, and 7, with element 7 being moved to the end.
The values of 4, 8, 5, and 6 can be obtained by removing element 7 from the resulting vector and inserting element 8 after the final vector element. The second component, which replaced the one that we had just introduced, is then removed.
Following that, we construct "vec2" and switch the elements of both vectors so that "vec" now equals "10, 20, 30" and "vec2" is "4, 5, 6." So all of the elements have been eliminated from "vec," a 9-element has been added at the beginning of the word, and an 11-element has been added to the end.
This can be observed in the screenshot above; every one of these results in "vec" being "9, 11" and "vec2" being "10, 20, 30."
What are the time and space complexities of using Vectors
Although it depends on the functions being utilized, in general, the time complexity of most operations is O(1). It follows that accessing, adding, or deleting elements is not contingent on the size of the vector, provided that the components are not added towards the final stage, and the array isn't enlarged.
The temporal complexity of changing elements in the middle is frequently O(n), as it depends upon moving the other elements. Because of the fact that the complexity of space is inversely correlated with vector size, it is equal to O(n).