DEV Community

Harsh Mishra
Harsh Mishra

Posted on

Vector: Container, C++

Vector Container in C++: Usage and Operations

In C++, the vector container is part of the Standard Template Library (STL) and is one of the most widely used data structures. It provides dynamic resizing and allows random access to elements. Vectors are particularly useful when you need to store a collection of items that can grow or shrink in size and when you want to access elements by their index quickly.

In this guide, we will cover everything you need to know about the vector container, including how to construct vectors, how to perform common operations, and how to take full advantage of its capabilities in C++.

Table of Contents

  1. Introduction to Vector in C++
  2. Different Ways to Construct a Vector
  3. Common Operations on Vector
    • push_back()
    • pop_back()
    • insert()
    • erase()
    • at()
    • size()
    • empty()
    • clear()
  4. Working with Custom Data Types
  5. Iterators in Vectors
  6. Vector of Vectors
  7. Summary and Best Practices

1. Introduction to Vector in C++

A vector in C++ is a dynamic array that can grow or shrink in size. Unlike arrays, which have a fixed size, vectors manage their size dynamically, providing flexibility when handling collections of data. It supports random access, meaning you can directly access any element in constant time, which makes vectors efficient for many operations.

Key Features:

  • Dynamic Sizing: Vectors can grow or shrink dynamically as elements are added or removed.
  • Random Access: Vectors support constant time access to any element using indices.
  • Contiguous Memory Allocation: Like arrays, elements in a vector are stored in contiguous memory locations, providing cache efficiency.
  • Efficient Insertion/Deletion at the End: Vectors can efficiently add or remove elements at the end with push_back() and pop_back(), respectively.

2. Different Ways to Construct a Vector

The vector class in C++ can be constructed in multiple ways depending on the desired behavior.

2.1 Default Constructor

You can create an empty vector using the default constructor.

vector<int> v;
Enter fullscreen mode Exit fullscreen mode

This creates an empty vector of integers, and you can add elements later.

2.2 Constructor with Initial Size

You can create a vector with a specific size, where each element is initialized to the default value for the element type.

vector<int> v(5);  // Creates a vector of size 5 with default-initialized elements (0 for int)
Enter fullscreen mode Exit fullscreen mode

If you want to initialize the elements to a specific value, you can provide a second argument.

vector<int> v(5, 10);  // Creates a vector of size 5 with each element initialized to 10
Enter fullscreen mode Exit fullscreen mode

2.3 Constructor with an Initializer List

You can initialize a vector directly with a list of values.

vector<int> v = {1, 2, 3, 4, 5};
Enter fullscreen mode Exit fullscreen mode

This creates a vector containing the values 1, 2, 3, 4, and 5.

2.4 Constructor with Another Container

You can also create a vector by copying the contents of another container (like another vector or array).

vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2(v1);  // Creates a vector that is a copy of v1
Enter fullscreen mode Exit fullscreen mode

2.5 Constructor with Iterators

You can initialize a vector using a range of iterators from another container. Note that you cannot directly pass containers like deque or list to the vector constructor, but you can use their iterators (.begin() and .end()) to initialize the vector.

vector<int> v(v1.begin(), v1.end());  // Initializes a vector using iterators from another vector
Enter fullscreen mode Exit fullscreen mode

You can also use iterators from other containers like deque or list to initialize a vector, as shown below:

deque<int> d = {1, 2, 3, 4, 5};
vector<int> v(d.begin(), d.end());  // Initializes a vector using iterators from a deque

list<int> l = {10, 20, 30};
vector<int> v2(l.begin(), l.end());  // Initializes a vector using iterators from a list
Enter fullscreen mode Exit fullscreen mode

However, note that you cannot directly pass the entire deque or list container to the vector constructor; you must use .begin() and .end() to specify the range.

Similarly, you can use iterators from arrays. To initialize a vector from an array, you can use the array's beginning and ending pointers. For example, if you have an array like arr:

int arr[] = {1, 2, 3, 4, 5};
vector<int> v(arr, arr + 5);  // Initializes a vector using pointers to an array
Enter fullscreen mode Exit fullscreen mode

In this case, arr is the array, and arr + 5 specifies the range of elements to be used from the array (from the start to the fifth element, exclusive). This way, you can initialize the vector directly from an array.

2.6 Assignment Operator

You can use the assignment operator to copy elements from one vector to another.

vector<int> v1 = {1, 2, 3};
vector<int> v2;
v2 = v1;  // Now v2 contains the same elements as v1
Enter fullscreen mode Exit fullscreen mode

The assignment operator performs a deep copy, meaning that the elements of v1 are copied into v2, not just the pointer or reference.


3. Common Operations on Vector

3.1 push_back()

The push_back() function adds an element to the end of the vector. This operation is amortized constant time.

Syntax:

v.push_back(element);
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
Enter fullscreen mode Exit fullscreen mode

After this, the vector v will contain: [10, 20, 30].

3.2 pop_back()

The pop_back() function removes the last element from the vector. This operation is constant time.

Syntax:

v.pop_back();
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v = {10, 20, 30};
v.pop_back();  // Removes 30
Enter fullscreen mode Exit fullscreen mode

After calling pop_back(), the vector will contain: [10, 20].

3.3 insert()

The insert() function allows you to insert an element at a specific position in the vector. It can be used to insert a single element or multiple elements at once. Additionally, you can insert a range of elements or elements from another container, such as a vector.

Syntax:

  • Insert a single element:
  v.insert(position, element);
Enter fullscreen mode Exit fullscreen mode
  • Insert multiple identical elements:
  v.insert(position, count, element);
Enter fullscreen mode Exit fullscreen mode
  • Insert elements from another container (e.g., vector, list):
  v.insert(position, container.begin(), container.end());
Enter fullscreen mode Exit fullscreen mode

Example 1: Insert a Single Element

vector<int> v = {10, 20, 30};
v.insert(v.begin() + 1, 15);  // Inserts 15 at position 1
Enter fullscreen mode Exit fullscreen mode

After this, the vector v will contain: [10, 15, 20, 30].

Example 2: Insert Multiple Identical Elements

v.insert(v.begin() + 2, 3, 100);  // Inserts three 100's starting from position 2
Enter fullscreen mode Exit fullscreen mode

After this, the vector v will contain: [10, 15, 100, 100, 100, 20, 30].

Example 3: Insert Elements from Another Vector

vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
v1.insert(v1.end(), v2.begin(), v2.end());  // Inserts all elements from v2 at the end of v1
Enter fullscreen mode Exit fullscreen mode

After this, the vector v1 will contain: [1, 2, 3, 4, 5, 6].

3.4 erase()

The erase() function removes elements from the vector at a specified position or a range of positions. Similar to insert(), erase() can be used to remove a single element, multiple elements, or a range of elements.

Syntax:

  • Erase a single element:
  v.erase(position);
Enter fullscreen mode Exit fullscreen mode
  • Erase a range of elements:
  v.erase(start, end);  // Removes elements from start to end-1
Enter fullscreen mode Exit fullscreen mode

Example 1: Erase a Single Element

vector<int> v = {10, 20, 30};
v.erase(v.begin() + 1);  // Removes element at position 1 (20)
Enter fullscreen mode Exit fullscreen mode

After this, the vector v will contain: [10, 30].

Example 2: Erase a Range of Elements

vector<int> v = {10, 20, 30, 40, 50};
v.erase(v.begin() + 1, v.begin() + 4);  // Removes elements from position 1 to 3 (20, 30, 40)
Enter fullscreen mode Exit fullscreen mode

After this, the vector v will contain: [10, 50].


3.5 at()

The at() function retrieves an element at a specified index with bounds checking. If the index is out of bounds, it throws an out_of_range exception.

Syntax:

element = v.at(index);
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v = {10, 20, 30};
cout << v.at(1) << endl;  // Outputs: 20
Enter fullscreen mode Exit fullscreen mode

3.6 size()

The size() function returns the number of elements in the vector.

Syntax:

size_t size = v.size();
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v = {10, 20, 30};
cout << "Size of vector: " << v.size() << endl;  // Outputs: 3
Enter fullscreen mode Exit fullscreen mode

3.7 empty()

The empty() function checks whether the vector is empty.

Syntax:

bool isEmpty = v.empty();
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v;
cout << "Is vector empty? " << (v.empty() ? "Yes" : "No") << endl;  // Outputs: Yes
v.push_back(10);
cout << "Is vector empty? " << (v.empty() ? "Yes" : "No") << endl;  // Outputs: No
Enter fullscreen mode Exit fullscreen mode

3.8 clear()

The clear() function removes all elements from the vector.

Syntax:

v.clear();
Enter fullscreen mode Exit fullscreen mode

Example:

vector<int> v = {10, 20, 30};
v.clear();  // Removes all elements
Enter fullscreen mode Exit fullscreen mode

After calling clear(), the vector will be empty.


4. Working with Custom Data Types

Vectors can also store custom data types such as classes or structs. When working with custom types, remember to define appropriate constructors, destructors, and operators if necessary.

Example:

class Student {
public:
    string name;
    int age;

    Student(string n, int a) : name(n), age(a) {}
};

vector<Student> students;
students.push_back(Student("John", 20));
students.push_back(Student("Alice", 22));
Enter fullscreen mode Exit fullscreen mode

5. Iterators in Vectors

Vectors support iterators that allow you to iterate over the elements in a way similar to arrays but with more flexibility. The begin() and end() functions return iterators pointing to the first and one-past-the-last elements of the vector, respectively.

5.1 Example Using Iterators

vector<int> v = {10, 20, 30};
for (auto it = v.begin(); it != v.end(); ++it) {
    cout << *it << " ";  // Output: 10 20 30
}
Enter fullscreen mode Exit fullscreen mode

6. Vector of Vectors

A vector can hold other vectors, allowing you to create a matrix-like structure.

Example:

vector<vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
Enter fullscreen mode Exit fullscreen mode

You can access elements with two indices:

cout << matrix[0][1] << endl;  // Outputs: 2
Enter fullscreen mode Exit fullscreen mode

7. Summary and Best Practices

  • Vectors are a powerful and flexible container in C++ for managing dynamic arrays.
  • Always use push_back() to add elements to the end and pop_back() to remove elements.
  • If you know the size in advance, consider using reserve() to reduce reallocations.
  • Be mindful of the costs of inserting and erasing elements in the middle of the vector, as these operations may shift many elements.
  • Vectors are great when you need random access and efficient resizing but may not be the best choice for frequent insertions/deletions at the front.

By understanding and leveraging vectors in C++, you can efficiently handle dynamic collections and improve the performance and flexibility of your programs.

Top comments (0)