VECTORS IN C++
In classic arrays in C++ (e.g. int arr[10]), the size must be defined in advance
and cannot be changed during program execution.
However, in real-world problems we often do not know in advance how much data we will need to store.
This is where std::vector comes in — a data structure that behaves like an array, but can automatically grow and shrink in size.
Here, the dimensions (3) must be specified in square brackets and cannot be changed further.
Unlike a sheet, the dimension of a vector can be changed during the program.
Include header file: vector
using namespace std;
Otherwise, you would have to write std::vector every time you want to call a vector
Example of vector usage:
using namespace std;
vector<int>a(10);
Here is:
- vector-vector identification
- <int> - data type used in the vector, in this case integer
- a - vector name
a[3]
Basic Manipulation of std::vector in C++
This example demonstrates how to use std::vector as a dynamic array in C++.
You will see how to add elements using push_back(), iterate through elements using
a range-based loop, and get the number of elements with size().
#include <iostream> // for input/output (cout)
#include <vector> // for std::vector
using namespace std;
int main() {
// Creating an empty vector of integers
vector<int> numbers;
// Adding elements to the vector (dynamic resizing happens automatically)
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// Printing vector elements using range-based for loop
cout << "Vector elements: ";
for (int num : numbers) {
cout << num << " ";
}
// Printing the number of elements in the vector
cout << "\nVector size: " << numbers.size() << endl;
return 0;
}
Vector methods in C++
Adding an element to the end of a vector
example of adding the number 13 to the end of vector a:
Vector size in c++
Getting the Number of Elements in a Vector
This example shows how to determine the number of elements stored in a std::vector using the size() method.
#include <iostream> // for cout
#include <vector> // for std::vector
using namespace std;
int main() {
// Initializing a vector with 5 elements
vector<int> b = {10, 20, 30, 40, 50};
// Printing the number of elements in the vector
cout << "Number of elements in the vector is "
<< b.size()
<< "." << endl;
return 0;
}
Taking the first element from a vector
Accessing the First Element of a Vector
This example demonstrates how to access the first element of a std::vector using the front() function.
#include <iostream> // for cout
#include <vector> // for std::vector
#include <string> // for std::string
using namespace std;
int main() {
// Initializing a vector of strings
vector<string> groups = {"Michael", "Peter", "Lazar", "Natasha"};
// Accessing the first element of the vector
cout << "The first in the group is "
<< groups.front()
<< endl;
return 0;
}
The front() function returns the first element in the vector.
It is important to note that the vector must not be empty when calling this function.
Retrieving the last element in a vector
Accessing the Last Element of a Vector
This example demonstrates how to access the last element of a std::vector using the back() function.
#include <iostream> // for cout
#include <vector> // for std::vector
#include <string> // for std::string
using namespace std;
int main() {
// Initializing a vector of strings
vector<string> group = {"Michael", "Peter", "Lazar", "Natasha"};
// Accessing the last element of the vector
cout << "The last one in the group is "
<< group.back()
<< endl;
return 0;
}
The back() function returns the last element in the vector.
Make sure the vector is not empty before calling back(), otherwise the behavior is undefined.
Inserting a value at a specific position in a vector
auto itr=numbers.begin() + pos;
numbers.insert(itr, 3);
A array of values can also be added to a specific position. For example. if at position 3 now, we want to insert the following array:
auto itr=numbers.begin() + pos;
numbers.insert(itr, {11, 12, 13});
Deleting the last element of the vector
The following example shows the application of this method:
Removing the Last Element from a Vector
This example shows how to remove the last element from a std::vector using the pop_back() function.
#include <iostream> // for cout
#include <vector> // for std::vector
using namespace std;
int main() {
// Initializing a vector of double values (temperatures)
vector<double> temperatures = {23.2, 25.8, 11, 15.3, 17};
// Print original vector
cout << "Original temperatures: ";
for(double t : temperatures) {
cout << t << " ";
}
cout << endl;
// Remove the last element
temperatures.pop_back();
// Print vector after removing last element
cout << "After pop_back(): ";
for(double t : temperatures) {
cout << t << " ";
}
cout << endl;
return 0;
}
The pop_back() function removes the last element of the vector.
Make sure the vector is not empty before calling pop_back(), otherwise the behavior is undefined.
Deleting a vector element at a specific position
Example:
Deleting an Element from a Vector using erase()
This example demonstrates how to delete a specific element from a std::vector using the erase() function.
#include <iostream> // for cout
#include <vector> // for std::vector
using namespace std;
int main() {
// Initialize a vector with three elements
vector<int> c = {2, 3, 4};
// Print original vector
cout << "Original vector: ";
for(int num : c) {
cout << num << " ";
}
cout << endl;
// Delete the element at position 1 (second element)
c.erase(c.begin() + 1); // removes the value 3
// Print vector after deletion
cout << "After erase(): ";
for(int num : c) {
cout << num << " ";
}
cout << endl;
return 0;
}
The erase() function removes the element at the specified position.
Note that vector indices start at 0, so c.begin() + 1 refers to the second element.
All subsequent elements are shifted one position to the left.
Deleting all vector elements in c++
Usage example:
using namespace std;
vector < int > c={2,3,4};
c.clear();//deletes all elements in the vector
Printing the elements of a vector
using namespace std;
vector < int > numbers={1,2,3,4,5};
{
cout << endl;
Test your code here!
Reading text data from standard input and inserting one by one into a vector
#include <iostream>
#include <string>
using namespace std;
// Declare a vector of strings to store the input words
vector<string> text;
// Variable to hold each word from input
string word;
// Read words from standard input until EOF or an error occurs
while(cin >> word)
{
text.push_back(word);
Iterating through the elements of a vector using an iterator []
for(int i = 0; i < text.size(); i++)
{
cout << endl;
Iterating through the elements of a vector using an iterator
using namespace std;
vector < int > points={5,3,5,7,8,2,3,4};
cout << "Number of points per task:\n " << endl;
for(vector < int >::iterator it=points.begin(); it != points.end(); ++it)
{
cout << endl;
v.begin() – returns an iterator pointing to the initial element of the container
v.end() – returns an iterator pointing "behind the last" element of the container.
Sorting vectors in c++ with the sort library function
using namespace std;
vector < int > A={4,2,7,5,9};
sort(A.begin(),A.end());
//printing
Important std::vector Methods
Vectors in C++ provide many useful methods for managing dynamic arrays. Below are the basic methods, along with examples demonstrating their usage.
Basic Methods
| Method | Description |
|---|---|
| push_back() | Adds an element to the end of the vector. |
| pop_back() | Removes the last element from the vector. |
| size() | Returns the number of elements in the vector. |
| clear() | Deletes all elements from the vector. |
| at() | Accesses an element at a specified index with bounds checking. |
Examples of Method Usage
1. Adding Elements – push_back()
The push_back() method is used for dynamically adding elements to a vector.
#include <iostream> #include <vector> int main() { std::vector<int> numbers; numbers.push_back(10); // Adds 10 numbers.push_back(20); // Adds 20 std::cout << numbers[0] << ", " << numbers[1] << "\n"; return 0; }
2. Removing Elements – pop_back()
The pop_back() method removes the last element from the vector.
#include <iostream> #include <vector> int main() { std::vector<int> numbers = {10, 20, 30}; numbers.pop_back(); // Removes 30 std::cout << numbers.size() << "\n"; // Prints 2 return 0; }
3. Getting Size – size()
The size() method returns the number of elements in the vector.
#include <iostream> #include <vector> int main() { std::vector<int> numbers = {1, 2, 3, 4}; std::cout << "Vector size: " << numbers.size() << "\n"; return 0; }
4. Deleting All Elements – clear()
The clear() method removes all elements from the vector, leaving it empty.
#include <iostream> #include <vector> int main() { std::vector<int> numbers = {1, 2, 3}; numbers.clear(); std::cout << "Vector is empty: " << numbers.size() << "\n"; return 0; }
5. Accessing Elements – at()
The at() method allows access to an element with bounds checking.
#include <iostream> #include <vector> int main() { std::vector<int> numbers = {5, 10, 15}; std::cout << numbers.at(1) << "\n"; // Accesses element at index 1 return 0; }
More Detailed Code Examples
To better understand the practical use of std::vector in C++, here are some examples showing declaration, initialization, and manipulation of vectors.
Declaration and Initialization of Vectors
Below is an example of basic vector declaration and initialization:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
In this example, the vector numbers is initialized with five elements and printed in a loop.
Adding and Removing Elements
Vectors allow dynamic addition and removal of elements using the push_back and pop_back methods:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
std::cout << "The vector contains: ";
for (int number : numbers) {
std::cout << number << " ";
}
numbers.pop_back(); // Removes the last element
std::cout << "\nAfter pop_back: ";
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
With this approach, we can easily add and remove elements from the vector without manually managing memory.
Iteration and Accessing Elements
We can use indexing or an iterator to traverse the vector:
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> names = {"Anna", "Mark", "John"};
for (size_t i = 0; i < names.size(); i++) {
std::cout << names[i] << " ";
}
std::cout << "\nUsing iterator: ";
for (auto it = names.begin(); it != names.end(); ++it) {
std::cout << *it << " ";
}
return 0;
}
This approach demonstrates different ways to traverse a vector – using classic indexing and an iterator.
Conclusion
Vectors in C++ provide a flexible and efficient alternative to static arrays, offering dynamic allocation and useful methods for working with data. By understanding these basic operations, developers can efficiently manage arrays of data in their applications.
Advanced Features
Vectors in the C++ standard library offer a wide range of methods for data manipulation. This section covers advanced topics such as iteration, adding, and removing elements using push_back, insert, and erase, as well as the difference between size and capacity.
Iterating Through a Vector
There are multiple ways to iterate through a vector – using classic indexing, a range-based for loop, and iterators:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "Classic indexing: ";
for (size_t i = 0; i < numbers.size(); i++) {
std::cout << numbers[i] << " ";
}
std::cout << "\nRange-based for loop: ";
for (int number : numbers) {
std::cout << number << " ";
}
std::cout << "\nIterator: ";
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
return 0;
}
Adding and Inserting Elements
Besides push_back, which adds an element to the end of the vector, we can use insert to insert elements at arbitrary positions.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30};
numbers.push_back(40); // Adds 40 to the end
numbers.insert(numbers.begin() + 1, 15); // Inserts 15 at the second position
std::cout << "Vector after insertion: ";
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Removing Elements
The erase method is used to remove individual elements or a range of elements from a vector.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30, 40, 50};
numbers.erase(numbers.begin() + 2); // Removes the third element (30)
numbers.erase(numbers.begin(), numbers.begin() + 2); // Removes the first two values
std::cout << "Vector after removal: ";
for (int number : numbers) {
std::cout << number << " ";
}
return 0;
}
Difference Between size and capacity
The size() method returns the number of elements in the vector, while capacity() indicates how many elements can fit in the currently allocated space.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
std::cout << "Initial size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << "\n";
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
std::cout << "After adding elements: " << numbers.size()
<< ", capacity: " << numbers.capacity() << "\n";
return 0;
}
Comparison with Other Containers
The C++ Standard Library offers multiple containers for data storage, with the most commonly used being
std::vector, std::array, and std::list.
Each of them has specific characteristics that make them suitable for particular situations.
Comparison of Key Features
| Feature | std::vector | std::array | std::list |
|---|---|---|---|
| Size | Dynamic, can grow | Fixed, determined at creation | Dynamic |
| Access Speed | O(1) – direct access via indexing | O(1) – direct access via indexing | O(n) – the list must be traversed to reach the desired element |
| Adding/Removing Elements | Efficient at the end (O(1)), slow at the beginning and in the middle (O(n)) | Not possible (fixed size) | Efficient anywhere (O(1)), but without direct access |
| Internal Structure | Memory array, elements are stored sequentially | Static array, elements are stored sequentially | Linked list, each element contains pointers to the next/previous |
When to Use Which Container?
- std::vector: When dynamic size and fast indexed access are needed.
- std::array: When the array size is known and minimal overhead is required.
- std::list: When frequent insertions or deletions at the beginning/middle of the structure are necessary.
Practical Examples
1. Using std::vector
std::vector is excellent when elements need to be dynamically added.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3};
numbers.push_back(4); // Adds an element to the end
std::cout << "Third element: " << numbers[2] << "\n"; // O(1) access
return 0;
}
2. Using std::array
std::array is a static array that uses stack memory, making it faster when the size is known.
#include <iostream>
#include <array>
int main() {
std::array<int, 3> numbers = {10, 20, 30};
std::cout << "First element: " << numbers[0] << "\n"; // O(1) access
return 0;
}
3. Using std::list
std::list is useful when frequent insertion or deletion at any position is needed.
#include <iostream>
#include <list>
int main() {
std::list<int> numbers = {10, 20, 30};
numbers.push_front(5); // Adds 5 to the beginning
numbers.erase(numbers.begin()); // Removes the first element
std::cout << "First element after removal: " << *numbers.begin() << "\n";
return 0;
}
Conclusion
The choice between std::vector, std::array, and std::list
depends on program needs. If fast element access and dynamic growth are required,
std::vector is the best choice. If a fixed size with minimal memory overhead is needed,
use std::array. If frequent additions and deletions from various positions are necessary,
std::list is the better option.
Discussion on Efficiency and Usage
Vectors in C++ have many advantages compared to static arrays, especially when working with dynamic data. However, their usage comes with certain trade-offs. Below, the advantages and potential drawbacks of vectors are explained, along with examples for better understanding.
Advantages of Vectors
| Feature | Description |
|---|---|
| Dynamic Size | Vectors automatically adjust their size based on the number of elements, unlike static arrays with a fixed size. |
| Ease of Use | Vectors come with built-in methods for adding, removing, and searching elements. |
| Safety | Methods like at() allow bounds checking, preventing access to non-existent elements. |
Example: Dynamic Expansion
One of the biggest advantages of vectors is automatic expansion, which allows working with an unknown number of elements during program execution.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
for (int i = 1; i <= 10; ++i) {
numbers.push_back(i); // Dynamically adds numbers from 1 to 10
}
for (int number : numbers) {
std::cout << " " << number << " ";
}
return 0;
}
Disadvantages of Vectors
| Feature | Description |
|---|---|
| Memory Preallocation | Vectors allocate extra memory to reduce reallocation frequency, which can lead to inefficient memory usage. |
| Performance | When a vector expands, reallocation of elements is required, which can be costly in terms of execution time. |
Example: Reallocation Effect
When a vector expands, new memory is allocated, and existing elements are copied to the new location. This can cause performance degradation in cases of frequent element additions.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
for (int i = 1; i <= 100000; ++i) {
numbers.push_back(i); // Frequent expansion due to element additions
}
std::cout << "Total number of elements: " << numbers.size() << "\n";
return 0;
}
Conclusion
Vectors are ideal for scenarios where the size of data is variable, as they simplify working with dynamic structures.
However, it is essential to consider their limitations, such as potential inefficiencies in memory usage and
performance in cases of frequent expansions. In such situations, it may be better to consider other data structures,
such as std::deque or std::list.
Advanced Topics
In addition to basic operations, vectors in C++ allow working with advanced concepts such as iterators, the difference between capacity and size, and working with 2D vectors (vectors of vectors). These topics are essential for advanced handling of dynamic data structures in more complex scenarios.
1. Iterators for Traversing a Vector
Iterators provide a flexible and efficient way to traverse vector elements, offering control over elements without directly using indices.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << "Element: " << *it << "\n";
}
return 0;
}
Iterators are used with functions like begin() and end(), where *it
accesses the value at the iterator's current position.
2. Difference Between Capacity and Size
Size (size()) represents the current number of elements in the vector, while capacity
(capacity()) indicates how many elements the vector can hold before memory reallocation occurs.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
numbers.push_back(10);
numbers.push_back(20);
std::cout << "Size: " << numbers.size()
<< ", Capacity: " << numbers.capacity() << "\n";
numbers.reserve(100); // Reserves space for 100 elements
std::cout << "Capacity after reserve: " << numbers.capacity() << "\n";
return 0;
}
Reserving capacity in advance can improve performance when a large number of additional elements is expected.
3. Working with 2D Vectors (Vectors of Vectors)
Vectors of vectors allow working with matrices or tabular data. Each element of the main vector can be another vector, creating a structure similar to a 2D array.
#include <iostream>
#include <vector>
int main() {
std::vector<std::vector<int>> matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
std::cout << "Element [0][1]: " << matrix[0][1] << "\n";
for (int i = 0; i < matrix.size(); ++i) {
for (int j = 0; j < matrix[i].size(); ++j) {
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Vectors of vectors are more flexible than traditional 2D arrays, as each "row" can have a different number of columns.
Conclusion
These advanced topics provide significant flexibility when working with data in C++. Understanding iterators, the difference between capacity and size, and working with multidimensional structures allows for efficient use of vectors in more complex scenarios.
Practical Exercises
To better understand the use of vectors in C++, we suggest several simple exercises for practice. These exercises cover input and processing of vector elements, as well as the application of basic methods and loops.
1. Entering n numbers and printing them in reverse order
Task: Allow the user to enter n numbers into a vector and then print those numbers in reverse order.
#include <iostream>
#include <vector>
int main() {
int n;
std::cout << "Enter the number of elements: ";
std::cin >> n;
std::vector<int> numbers(n);
for (int i = 0; i < n; ++i) {
std::cout << "Enter number " << i + 1 << ": ";
std::cin >> numbers[i];
}
std::cout << "Numbers in reverse order:\n";
for (int i = n - 1; i >= 0; --i) {
std::cout << numbers[i] << " ";
}
std::cout << "\n";
return 0;
}
2. Filtering even numbers from a vector
Task: Enter a sequence of numbers and extract all even numbers into a new vector.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> evenNumbers;
for (int number : numbers) {
if (number % 2 == 0) {
evenNumbers.push_back(number);
}
}
std::cout << "Even numbers:\n";
for (int number : evenNumbers) {
std::cout << number << " ";
}
std::cout << "\n";
return 0;
}
3. Calculating the average of elements
Task: Enter a sequence of numbers and calculate their average.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30, 40, 50};
int sum = 0;
for (int number : numbers) {
sum += number;
}
double average = static_cast<double>(sum) / numbers.size();
std::cout << "Average: " << average << "\n";
return 0;
}
Conclusion
These exercises provide practical examples for understanding basic vector operations, such as input, filtering, and aggregation. It is recommended to extend the exercises further for practice, for example, by adding input validation or working with larger data sets.
Adding Resources
To further expand your knowledge of vectors and their usage in C++, we recommend the following resources. These materials cover both basic and advanced topics, providing theoretical foundations and practical examples.
1. Official Documentation
The official documentation of the C++ standard library provides detailed information on all vector functions and methods, along with usage examples. It is recommended for precise and reliable information.
2. Online Courses
If you prefer an interactive learning approach, the following online courses provide in-depth lessons on working with vectors and other concepts in C++:
- Udemy: Beginning C++ Programming - From Beginner to Beyond
- Coursera: Programming in C++
- Pluralsight: C++ Fundamentals
3. Relevant Books
Books on C++ programming often include extensive information on vectors. Here are some recommended titles for different knowledge levels:
- "The C++ Programming Language" - Bjarne Stroustrup (creator of C++)
- "Effective Modern C++" - Scott Meyers (an excellent guide to modern C++)
- "C++ Primer" - Stanley B. Lippman, Josée Lajoie, Barbara E. Moo (a great book for beginners and intermediate learners)
4. Guides and Tutorials
The following tutorials and guides provide practical instructions and examples:
5. Discussions and Communities
Participating in communities and forums can help you solve specific problems and learn from others. Recommended communities:
Conclusion
Learning from various resources provides a broad spectrum of knowledge and helps in understanding how vectors are used in real-world projects. A combination of theory, practical exercises, and community engagement is recommended for a comprehensive grasp of this topic.
|
Previous
|< Introduction to arrays in C++ |
Next
Two dimensional array-matrix >| |