Vectors In STL

Role Of Vectors In STL With Examples.

So far, in this C++ series, we have seen static arrays which have a fixed size.

If in the middle of the program we have to store more elements in the array, then it becomes impossible and we are sure to get ‘out_of_bound’ exception, the moment we attempt to store elements beyond the array limits.

One solution for this is having the array declared with the maximum capacity so that we will not find any problem in storing more elements at runtime. But this arrangement has a serious disadvantage in that i.e. we are wasting too much memory.

=> Check The Complete C++ Training Series Here.

VECTORS IN STL

The answer to all these issues is using a dynamic array that will expand on its own as the need arises. STL provides this dynamic array in the form of a vector container.

How Do We Define Vectors?

Vectors are dynamic array containers that resize it automatically when elements are inserted or deleted. Storage of vector is handled by the vector container itself.

The elements in the vector are stored in contiguous locations. Just like arrays, vector elements also can be traversed and accessed using iterators.

Declaring A Vector In C++ With std:: Vector Class

In STL vector class ‘std::vector’ is defined under the header <vector>. Thus, in order to use a vector container, we should include this header in our program as shown below:

#include <vector>

We can declare an empty vector as shown below:

std::vector<int> myvec;

The above line of code will create a vector with the elements of type integer. In memory, this will be laid out as myvec.

Initialize Vector

We can initialize a vector with value at the time of declaring it.

This is done as follows:

#include<vector>
int main()
{
                 std::vector<int> myvec = {1, 1, 2, 3, 5};
}

In the above code, we declare a vector of type int named myvec containing the first five elements in the Fibonacci sequence.

The memory layout of this vector will be as below:

memory layout of vector

Vector Iterator

As already mentioned, we use iterators to traverse through the vector sequentially.

Vectors support the following iterator functions for stepping through the elements:

  • begin() – Returns iterator pointed to the first element of the vector container.
  • end() – Returns an iterator pointing to the element that follows the last element in the vector.
  • rbegin() – Returns a reverse iterator pointing to the last element in the vector container.
  • rend() – Returns a reverse iterator pointing to the first element of the vector container.
  • cbegin() – Returns a constant iterator pointing to the first element in the vector container.
  • cend() – Returns a constant iterator pointing to the element following the last element of the vector container.
  • crbegin() – Returns a reverse constant iterator pointing to the last element in the vector container.
  • crend() – Returns a reverse constant iterator pointing to the first element in the vector container.

Let’s see an Example that would demonstrate these iterator functions. The other functions can be used similarly.

#include <iostream>
#include <vector>
using namespace std;
int main()
   {
      vector<int> v1;
 
      for (int i = 1; i <= 5; i++)
         v1.push_back(i+1);
 
         cout << "Output of Vector with begin and end: ";
      for (auto i = v1.begin(); i != v1.end(); ++i)
         cout << *i << " ";
 
         cout << "\nOutput of Vector with rbegin and rend: ";
      for (auto itr = v1.rbegin(); itr != v1.rend(); ++itr)
         cout << *itr << " ";
  
         cout << "\nOutput Vector of with cbegin and cend: ";
      for (auto itc = v1.cbegin(); itc != v1.cend(); ++itc)
         cout << *itc << " ";
 
         cout << "\nOutput Vector of with crbegin and crend : ";
      for (auto icr = v1.crbegin(); icr != v1.crend(); ++icr)
         cout << *icr << " ";
         return 0;
}

Output:

Output of Vector with begin and end: 2 3 4 5 6
Output of Vector with rbegin and rend: 6 5 4 3 2
Output Vector of with cbegin and cend: 2 3 4 5 6
Output Vector of with crbegin and crend: 6 5 4 3 2

Thus in this code, we declare a vector and insert values in it using the push_back function. Then we display the vectors using each of the iterator functions that we described above. As you see from the output depending on the iterator functions used, the order in which the vector is displayed changes.

Vector Functions

Sorting a Vector

We can use STL algorithms that we have already seen on the vector.

Given below is the example of using ‘Sort’ on the vector.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
 {
   vector<int> myvec = {10,50,30,20,60,40};
 
   cout<<"Original Vector"<<endl;
   for(auto i=myvec.begin();i<myvec.end();++i)
      {
        cout<<*i<<" ";
      }
   cout<<endl;
 
   sort(myvec.begin(),myvec.end());
 
   cout<<"Sorted Vector"<<endl;
   for(auto i=myvec.begin();i<myvec.end();++i)
      {
        cout<<*i<<" ";
      }
   cout<<endl;
}

Output:

Original Vector
10 50 30 20 60 40
Sorted Vector
10 20 30 40 50 60

In the above example, we have initialized a vector and then applied a sort algorithm to sort the vector.

Printing Elements Of A Vector

Vectors can be printed by using an iterator and ‘cout’ stream. We can use an iterator to step through each of the vector elements and print them with cout.

The following Example shows this:

#include <iostream>
#include <vector>
using namespace std;
int main()
   {
      vector<int> v1;
   
      for (int i = 1; i <= 5; i++)
      v1.push_back(i+2);
      
      cout << "Output of Vector with begin and end: ";
      for (auto i = v1.begin(); i != v1.end(); ++i)
         cout << *i << " ";
 
}

Output:

Output of Vector with begin and end: 3 4 5 6 7

Vector Capacity

There are various functions which act on vectors to determine its size, maximum size, etc.

We list the functions as below:

(i) Size of the vector

The function size() returns the number of elements in the vector container. This is the in-built function of std::vector class and can be used directly to find the size of the vector.

Let us see an Example of a vector using the size() function:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
   vector<int> myvec = {1, 1, 2, 3, 5, 8};
   cout << "Vector Size : " << myvec.size();
 
   return 0;
}

Output:

Vector Size: 6

In the above program, we have defined a vector myvec consisting of six elements. Next, we call the size() function on myvec and it displays the correct size.

(ii) Resizing a vector

We can also resize a vector to the desired size such that it can hold ‘n’ number of elements. This is achieved by ‘resize()’ function of std:: vector class. The resize function takes the size of the vector as the parameter and then resizes the vector container to the specified size.

Let us understand this with the help of an Example.

#include <iostream>
#include <vector>
using namespace std;
int main()
{
   vector<int> myvec = {1, 1, 2, 3, 5, 8};
   cout << "\nVector elements are: ";
   for (auto it = myvec.begin(); it != myvec.end(); it++)
                 cout << *it << " ";
   myvec.resize(4);
   cout << "\nVector Size after resize: " << myvec.size();
   cout << "\nVector elements after resizing are: ";
   for (auto it = myvec.begin(); it != myvec.end(); it++)
                 cout << *it << " ";
   return 0;
}

Output:

Vector elements are: 1 1 2 3 5 8
Vector Size after resize: 4
Vector elements after resizing are: 1 1 2 3

In the above program, we initially define a vector myvec of size 6. Then we call the resize function on this vector with size=4. This means that we want to resize our vector to size 4 now.

After calling the resize function we print the vector again. We see that when we resize the vector to size 4, the remaining elements are discarded and only the 4 elements of the vector are displayed.

Apart from size and resize functions, vector class also supports some more functions that allow us to manipulate the capacity of the vector. They are:

  • max_size(): Returns maximum size i.e. the maximum number of elements the vector can hold.
  • capacity(): Returns the size of storage space currently allocated. This is returned in terms of the number of elements.
  • empty(): Checks whether the container is empty.
  • shrink_to_fit(): Shrinks the vector capacity to fit the size and discards all other elements.
  • reserve(): Reserves the vector capacity to contain n elements.

Vector Modifiers

Modifiers are operations or functions that may be used to modify the contents of the vector container. We will see some of the main functions that are used as modifiers.

Assigning New Values To Vector

One of the modifiers functions provided by std:: vector is the assign function. Assign function assigns new values to vector by replacing the old ones.

This is demonstrated in the following example.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
   // Assign vector
   vector<int> myvec;
   
   // assign value 10 5 times
   myvec.assign(5, 10);
 
   cout << "The vector elements: ";
   for (int i = 0; i < myvec.size(); i++)
      cout << myvec[i] << " ";
 
}

Output:

The vector elements: 10 10 10 10 10

In the above code, we declare a vector of type int. Then we call to assign a function with parameters 5, 10. This means that we intend to assign element 10 to the vector 5 times. When we display the vector, we see that the vector has 5 elements, all with value 5.

Erasing A Vector

The next function provided by std:: vector to modify a vector is the ‘erase’ function. Erase function removes the elements from the specified range or a position from the vector.

Let us see an Example of the Erase function.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
 // Initialize vector
 vector<int> myvec = {1,1,2,3,5};
 cout << "\nVector elements:";
 for (int i = 0; i < myvec.size(); i++)
   cout << myvec[i] << " ";
 
   // remove the first element
   myvec.erase(myvec.begin());
   cout<<"\nVector size after erase: "<<myvec.size();
 
   cout << "\nVector after erase operation: ";
for (int i = 0; i < myvec.size(); i++)
   cout<<myvec[i]<<" " ;
}

Output:

Vector elements:1 1 2 3 5

Vector size after erase: 4
Vector after erase operation: 1 2 3 5

As shown in the above output for resizing function we specify the range or position of the element to be erased or removed. In the above example, we have specified the position pointing to the first element in the vector.

Insert Elements Into The Vector

The vector class std:: vector provides yet another function to insert values into the vector. Insert function allows us to insert elements into the vector before the specified position.

This will be clear with the following Example.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
// Assign vector
vector<int> myvec = {2,3,4};
 
cout << "\nInitial vector: ";
for (int i = 0; i < myvec.size(); i++)
   cout << myvec[i] << " ";
 
// inserts 20 at the beginning, 30 after that
myvec.insert(myvec.begin(), 20);
myvec.insert(myvec.begin()+1,30);
cout << "\nNew vector after insert: ";
for (int i = 0; i < myvec.size(); i++)
   cout << myvec[i] << " ";
}

Output:

Initial vector: 2 3 4

New vector after insert: 20 30 2 3 4

The above program declares a vector with 3 elements initially. Then we call the insert function twice to insert values 20 and 30 at first and second positions in the vector respectively. Then we display the changed vector.

Swapping Vector Contents

The vector class also provides us with the ability to swap or exchange contents of one vector with that of another vector of the same type and size. This is achieved by vector built-in function ‘swap’.

Consider the following piece of code.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
   // swap operation
   vector<int> v1, v2;
   v1.push_back(1);
   v1.push_back(3);
   v2.push_back(5);
   v2.push_back(7);
 
   cout << "\n\nVector 1: ";
   for (int i = 0; i < v1.size(); i++)
      cout << v1[i] << " ";
 
   cout << "\nVector 2: ";
   for (int i = 0; i < v2.size(); i++)
      cout << v2[i] << " ";
 
   // Swaps v1 and v2
   v1.swap(v2);
 
   cout << "\nAfter Swap \nVector 1: ";
   for (int i = 0; i < v1.size(); i++)
      cout << v1[i] << " ";
 
   cout << "\nVector 2: ";
   for (int i = 0; i < v2.size(); i++)
      cout << v2[i] << " ";
}

Output:

Vector 1: 1 3
Vector 2: 5 7
After Swap
Vector 1: 5 7
Vector 2: 1 3

The above code shows the contents of two vectors before and after swapping.

Clearing Values In The Vector

In contrast to removing one or more elements from the vector by using the erase function, we have another function ‘Clear’ which allows us to remove all the elements in the vector container.

In the below program, we demonstrate a clear function of the vector container.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
   // swap operation
   vector<int> v1;
   v1.push_back(1);
   v1.push_back(3);
   v1.push_back(5);
   v1.push_back(7);
 
   cout<<"\nSize of vector v1: "<<v1.size();
   cout << "\n\nVector 1: ";
   for (int i = 0; i < v1.size(); i++)
      cout << v1[i] << " ";
 
   v1.clear();
   cout<<"\nSize of vector v1 after call to clear function : "<<v1.size();
}

Output:

Size of vector v1: 4
Vector 1: 1 3 5 7
Size of vector v1 after call to clearfunction : 0

Here we first declare a vector and then push elements into it. Once we call the function clear (), we see that all the elements in the vector are removed at once.

at(pos)

This function returns the reference to the element at position ‘pos’ within the vector.

This is one of the functions that is used to access the vector element.

An example is given below:

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
   // Assign vector
   vector<int> myvec = {1,1,2,3,5,8};
 
   cout<<"\nElement at position 3 : "<<myvec.at(3);
 
}

Output:

Element at position 3 : 3

As shown in the example, ‘at’ function is used to access the element in the vector at the specified position.

Front

Function ‘front’ returns the reference to the first element of the vector. This is yet another function that we use to access the elements of the vector container.

Following example shows the usage of ‘front’ function.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main()
{
   // Initialize vector
   vector<int> myvec = {1,1,2,3,5,8};
 
   cout<<"\nInput vector: ";
   for(auto it=myvec.begin();it<myvec.end();it++)
   cout<<*it<<" ";
   cout<<"\nElement at the front of vector: "<<myvec.front();
 
}

Output:

Input vector: 1 1 2 3 5 8
Element at the front of vector: 1

Back

Similar to the ‘front’ function, the back function is used to access the last element of the vector container. The ‘back’ function returns a reference to the last element in the vector container.

The following Example shows the ‘back’ function usage.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
  
int main()
{
     // Initialize vector
     vector<int> myvec = {1,1,2,3,5,8};
 
     cout<<"\nInput vector: ";
     for(auto it=myvec.begin();it<myvec.end();it++)
        cout<<*it<<" ";
  
     cout<<"\nElement at the back of vector: "<<myvec.back();
}

Output:

Input vector: 1 1 2 3 5 8
Element at the back of vector: 8

Find An Element In The Vector

The function ‘find’ is used to find if a particular element (referred to as key) is present in the vector or not. This function is supposed to be fast and efficient. Once the value is found the function returns.

The following example shows the usage of the find function.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main()
{
   // Assign vector
   vector<int> myvec = {1,1,2,3,5,8};
   cout<<"\nInput vector: ";
   for(auto it=myvec.begin();it<myvec.end();it++)
      cout<<*it<<" ";
   int key;
   cout<<"\nEnter the key to be searched: "; cin>>key;
   if(find(myvec.begin(),myvec.end(),key)!= myvec.end())
      cout<<"\nElement found";
   else
      cout<<"\nElement not found";
 
}

Output:

Input vector: 1 1 2 3 5 8
Enter the key to be searched: 0

Element not found

2D Vector

Two-dimensional vector is also known as ‘Vector of Vector”. Just like two-dimensional arrays, elements of two-dimensional vectors are also arranged in the matrix form.

An example program for 2D vector is given below.

#include <iostream>
#include <vector> // for 2D vector
using namespace std;
 
int main()
   {
      // Initializing 2D vector "odd_vect" with
      vector<vector<int> > odd_vect{ { 1, 3, 5 }, { 7, 9, 11 }, { 13,15,17 } };
       
      // Displaying the 2D vector
      cout<<"2D vector : ";
      cout<<endl;
      for (int i = 0; i < odd_vect.size(); i++) {
         for (int j = 0; j < odd_vect[i].size(); j++)
            cout << odd_vect[i][j] << " ";
         cout << endl;
}
 
      return 0;
}

Output:

2D vector :
1 3 5
7 9 11
13 15 17

In the above example, note the way in which the 2D vector is defined. It’s defined as a vector inside another vector. While displaying this 2D vector, we use the same approach as that of displaying 2D arrays.

Vector Example

Given below is a vector example that contains most of the vector operations.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
   {
      // Assign vector
      vector<int> myvec;
      // assign value 10 5 times
      myvec.assign(5, 10);
 
      cout << "The vector elements: ";
      for (int i = 0; i < myvec.size(); i++)
         cout << myvec[i] << " ";
 
      // push value 5 in myvec
      myvec.push_back(5);
      int n = myvec.size();
      cout << "\nThe new vector after push_back:";
      for (int i = 0; i < myvec.size(); i++)
         cout << myvec[i] << " ";
   
      // pop the element
      myvec.pop_back();
      cout<<"\nNew vector after pop_back : ";
      for (int i = 0; i < myvec.size(); i++)
         cout << myvec[i] << " ";
       
      // inserts 20 at the beginning
      myvec.insert(myvec.begin(), 20);
      cout << "\nNew vector after insert: ";
      for (int i = 0; i < myvec.size(); i++)
         cout << myvec[i] << " ";
 
      // remove the first element
      myvec.erase(myvec.begin());
      cout<<"\nVector size after erase: "<<myvec.size();
      cout << "\nAfter erase first element: ";
      for (int i = 0; i < myvec.size(); i++)
         cout<<myvec[i]<<" " ;
}

Output:

The vector elements: 10 10 10 10 10
The new vector after push_back:10 10 10 10 10 5
New vector after pop_back : 10 10 10 10 10
New vector after insert: 20 10 10 10 10 10
Vector size after erase: 5
After erase first element: 10 10 10 10 10

Following is the screenshot for the same.

vector Example Output

In the above example, we declare a vector and then using assign and push_back functions, enter elements in the vector. Then we use function pop_back to remove an element from the end of the vector. After that, we again add one element to the vector using the insert element and then erase the element using the erase function.

This is an end-to-end example of the vector container demonstrating its various functions.

Conclusion

With this, we have come to the end of this tutorial on vector.

In our upcoming tutorial, we will learn about the ‘list’ container of STL which is similar to the lines of arrays and vectors.

=> Check Out The Perfect C++ Training Guide Here.