In C++, vectors are a component of the standard template library (STL). They serve as dynamic arrays capable of adjusting their size automatically upon addition or removal of elements.
Unlike arrays that are fixed in size, vectors in C++ are highly flexible and versatile due to their extensive set of functions. This makes vectors a valuable data structure in C++. Vectors offer a variety of beneficial member functions like pushback, insert, size, clear, front, popback, and more.
A vector represents a type of sequence container that implements a dynamic array, allowing for automatic resizing when adding elements. Elements in a vector are stored in adjacent memory locations and memory allocation occurs dynamically during program execution. In situations where additional space is necessary, vectors allocate fresh memory, transfer existing elements to the new memory space, and handle the release of the old memory.
Syntax
It has the following syntax:
vector<T> v;
In this particular format,
- T signifies the type of components.
- v represents the identifier of the vector.
Creating a Vector
If we want to generate a vector, it is essential to incorporate the <vector> header.
std::vector<datatype> vector_name; // Empty vector
C++ Vector Example
Let's consider a basic example to demonstrate the C++ Vector data structure.
Example
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers; // Empty vector
vector<int> sizes(5); // Vector of 5 elements (default-initialized)
vector<int> values(3, 10); // Vector with 3 elements initialized to 10
vector<int> primes = {2, 3, 5, 7}; // Vector with initializer list
cout << "Vector created." << endl;
return 0;
}
Output:
Vector created
Inserting Elements
In C++, a value can be added to a vector using the insert function, which operates in linear time complexity. To add an element at the end of the vector, the push_back method is preferred for its quicker performance, executing in constant time complexity.
Syntax
It has the following system:
vector_name.push_back(value);
vector_name.insert(vector_name.begin() + index, value);
C++ Inserting Element in C++
Let's consider a basic illustration of adding elements in C++.
Example
#include <bits/stdc++.h>
using namespace std; //using standard namespace
int main() { //main function
vector<char> v = {'T', 'p', 'o', 'i'};
// Inserting 'z' at the back
v.push_back('t');
// Inserting 'n' at index 4
v.insert(v.begin() + 4, 'n');
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
return 0;
}
Output:
T p o i n t
Accessing of Updating Elements
We have the option to retrieve elements by utilizing either the operator or the at method. While the operator is efficient, it lacks safety as it does not validate if the specified index exists within the vector. Alternatively, we can employ the .at method for element access. Modifying elements involves simply assigning a new value based on their respective indices.
Syntax
It has the following syntax:
vector_name[index];
vector_name.at(index);
vector_name[index] = new_value;
Accessing and Updating Elements Example
Let's consider a scenario to demonstrate the process of accessing and modifying elements within vectors.
Example
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v = {'a', 'e', 'i', 'o', 'u'};
// Accessing and printing values
cout << "The Accessing Value at position 4 is: " << v[4] << endl; // Output: u
cout << "The Accessing Value at position 3 is: " << v.at(3) << endl; // Output: o
// Updating existing values
v[4] = 'y'; // Changes 'u' to 'y'
v.at(2) = 'z'; // Changes 'i' to 'z'
cout << "The Updating Value at Position 4 is: "<< v[4] << endl; // Output: y
cout << "The Updating Value at Position 2 is: "<< v.at(2) << endl; // Output: z
return 0;
}
Output:
The Accessing Value at position 4 is: u
The Accessing Value at position 3 is: o
The Updating Value at Position 4 is: y
The Updating Value at Position 2 is: z
Find Vector Size
One of the primary challenges associated with arrays is the requirement to manage a distinct variable to keep track of their size. This issue can be addressed by utilizing vectors, which offer the size method to efficiently determine the total number of elements present within the vector.
Syntax
It has the following Syntax:
vector_name.size();
Example to Find Vector Size
Let's consider an example to demonstrate the magnitude of vectors in C++.
Example
#include <iostream>
#include <vector>
using namespace std; //using standard namespace
int main() { //Main Function
vector<char> v = {'T', 'p', 'o', 'i', 'n', 't', 'T', 'e', 'c', 'h'};
// Finding size
cout << "The Size of Vector is: " << v.size();
return 0;
}
Output:
The Size of Vector is: 10
Traversing a Vector
We have the option to iterate through a vector using conventional for loops, range-based for loops, or iterators. We can employ the loop and ascertain the vector's size using the size method to iterate over its elements.
Example to Traverse a Vector
Let's consider an instance to demonstrate the process of iterating through a vector in C++.
Example
#include <iostream>
#include <vector>
using namespace std; //using standard namespace
int main() { //Main Function
vector<char> v = {'T', 'p', 'o', 'i', 'n', 't', 'T', 'e', 'c', 'h'};
// Traversing vector via range based for loop
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
return 0;
}
Output:
T p o i n t T e c h
Deleting Elements
Vectors enable the elimination of the final element or deletion of elements based on a specific condition by utilizing the erase and popback methods. When the value of a particular element within the vector is known, the find function can be employed to determine its position. Subsequently, the element can be removed efficiently using the popback function, which operates in constant time.
Syntax
It has the following syntax:
vector_name.pop_back();
vector_name.erase(vector_name.begin() + index);
Example of Delete Elements in a Vector
Let's consider an instance to demonstrate the process of removing elements from a vector in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm> // Required for std::find
using namespace std; // Using Standard Namespace
int main() { // Main Function
vector<char> v = {'T', 'p', 'o', 'i', 'n', 't'};
// Deleting the last element 't' from vector
v.pop_back();
// To find and delete 't'
auto it = find(v.begin(), v.end(), 't');
if (it != v.end()) {
v.erase(it);
}
// Print remaining elements
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
return 0;
}
Output:
T p o i n
Time Complexity of Vector Operations
| Operation | Time Complexity |
|---|---|
| Access (index) | O(1) |
| Insertion (end) | O(1) |
| Deletion (end) | O(1) |
| Insertion (mid) | O(n) |
| Deletion (mid) | O(n) |
Passing Vector to Functions
The vector can be transmitted by value (copying the data), reference (altering the original), or const reference (ensuring read-only access).
Syntax
It has the following syntax:
void modify(vector<int> v); // Pass by value
void modify(vector<int>& v); // Pass by reference
void print(const vector<int>& v); // Pass by const reference
Internal Working of Vectors
In C++, vectors have the ability to handle their storage automatically. When an element is inserted and there is insufficient capacity, the vector automatically adjusts its size by obtaining new memory, transferring existing elements to the new memory, and discarding the old memory. This process guarantees that the push_back operation executes in constant time over a series of operations.
Key points
- The capacity often exceeds the size.
- Capacity can be checked using capacity.
- If the size is known, use the reserve to pre-allocate the memory.
Multidimensional Vector
Vectors can be embedded within each other to form two-dimensional or three-dimensional arrangements. This technique proves beneficial for problem-solving scenarios that revolve around matrix operations.
Syntax:
It has the following syntax:
vector<vector<int>> matrix(rows, vector<int>(cols));
Multidimensional Vector Example
Let's consider a scenario to demonstrate the concept of a multidimensional array in C++.
Example
#include <iostream>
#include <vector>
using namespace std; // Using Standard Namespace
int main() { // Main Function
vector<vector<int>> matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
return 0; // Optional but recommended
}
Output:
1 2 3
4 5 6
7 8 9
Explanation
This code snippet generates a two-dimensional vector representing a matrix with a dimension of three rows by three columns. The vector is initialized with predefined values. Subsequently, nested loops are employed to display each element of the matrix in a sequential order by rows.
C++ Vector Functions
In C++, the vector container provides a variety of functions to carry out diverse operations. The following table displays the names of these functions along with their respective descriptions.
| Function | Description |
|---|---|
| at() | It provides a reference to an element. |
| back() | It gives a reference to the last element. |
| front() | It gives a reference to the first element. |
| swap() | It exchanges the elements between two vectors. |
| push_back() | It adds a new element at the end. |
| pop_back() | It removes a last element from the vector. |
| empty() | It determines whether the vector is empty or not. |
| insert() | It inserts new element at the specified position. |
| erase() | It deletes the specified element. |
| resize() | It modifies the size of the vector. |
| clear() | It removes all the elements from the vector. |
| size() | It determines a number of elements in the vector. |
| capacity() | It determines the current capacity of the vector. |
| assign() | It assigns new values to the vector. |
| operator=() | It assigns new values to the vector container. |
| operator_PRESERVE24__ | It access a specified element. |
| end() | It refers to the past-lats-element in the vector. |
| emplace() | It inserts a new element just before the position pos. |
| emplace_back() | It inserts a new element at the end. |
| rend() | Icpp tutorials the element preceding the first element of the vector. |
| rbegin() | Icpp tutorials the last element of the vector. |
| begin() | Icpp tutorials the first element of the vector. |
| max_size() | It returns the maximum number of elements that the vector can hold. |
| cend() | It refers to the past-last-element in the vector. |
| cbegin() | It refers to the first element of the vector. |
| crbegin() | It refers to the last character of the vector. |
| crend() | It refers to the element preceding the first element of the vector. |
| data() | It writes the data of the vector into an array. |
| shrinktofit() | It reduces the capacity and makes it equal to the size of the vector. |
C++ Vectors Example
Let's examine the code to showcase different vector operations in C++.
Example
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v1 = {10, 20, 30};
v1.push_back(40); // add element to end
v1.insert(v1.begin() + 1, 15); // insert at specific position
v1[2] = 25; // update element
v1.emplace(v1.begin() + 2, 17); // emplace element at specific position
v1.emplace_back(50); // emplace element at the end
cout << "Vector elements: ";
for (int val : v1) cout << val << " ";
cout << "\nSize: " << v1.size();
cout << "\nCapacity: " << v1.capacity();
cout << "\nMax Size: " << v1.max_size();
v1.pop_back(); // remove last element
v1.erase(v1.begin()); // erase first element
cout << "\nAfter deletion: ";
for (int val : v1) cout << val << " ";
cout << "\nFront: " << v1.front();
cout << "\nBack: " << v1.back();
cout << "\nAt(1): " << v1.at(1);
vector<int> v2 = {100, 200};
v1.swap(v2); // swap content
cout << "\nAfter swap v1: ";
for (int val : v1) cout << val << " ";
v1.clear(); // clear vector
cout << "\nIs v1 empty? " << (v1.empty() ? "Yes": "No");
v1.assign(3, 99); // assign new values
cout << "\nAfter assign: ";
for (int val : v1) cout << val << " ";
int* ptr = v1.data();
cout << "\nFirst element via data(): " << *ptr;
return 0;
}
Output:
Vector elements: 10 15 17 25 30 40 50
Size: 7
Capacity: 7
Max Size: 1073741823
After deletion: 15 17 25 30 40
Front: 15
Back: 40
At(1): 17
After swap v1: 100 200
Is v1 empty? Yes
After assign: 99 99 99
First element via data(): 99
Difference between Vector and Array
In C++, arrays and vectors are employed to hold groups of homogeneous data types, yet they vary in arrangement, adaptability, and memory handling.
| Feature | Array | Vector |
|---|---|---|
Size |
It can be fixed at compile time. | It can change dynamically at runtime. |
| Memory Management | Manual | Handled automatically by vector |
| Flexibility | Low | High (functions like push_back, insert) |
| STL Compatibility | Limited | Fully compatible |
| Bound Checking | Not provided | at() method offers bound checking |
| Initialization | int arr[5]; | vector_PRESERVE26__ v(5); |
In conclusion, the vectors in C++ are highly efficient, easy to use, and a strong option for raw arrays. They provide a rich set of tasks for dynamic resizing, insertion, deletion, and traversal and integrate well with the rest of STL. Mastering vectors will not only simplify the code but will also make it more efficient and cleaner. Whether we are handling complex structures or simple data such as matrics, vectors are our go-to tool in C++.
C++ Vectors MCQs
- What is an important feature that separates the vector from a traditional array in C++?
- Vectors can only store integer
- Vectors are of fixed size
- Vectors supports dynamic resizing
- The vector cannot be passed for tasks
- What happens internally when a C++ vector exceeds its current capacity?
- The program throws a runtime error
- Vector leaves old elements to take place
- Vector allocates new memory and copies existing elements
- Vector converts to a linked list
- Which of the following best describes the capacity function in the vector?
- Returns the number of times push_back was called
- Returns the number of elements that can be stored without reallocating
- Gives the actual memory address of the vector
- returns the number of elements removed from the vector
- What is the primary advantage of using a vector over raw arrays in C++?
- The vector does not require memory
- B vectors are slow but more readable
- The vector has the underlying dynamic size and utility functions
- vector does not support element access by index
- What does the reserve function do in terms of the vector?
- Set the exact size of the vector
- removes unused memory from the vector
- Constantly allocates memory to avoid reallocations
- Cleans the contents of the vector