2D Vectors in C++ – A Practical Guide 2D Vectors

Filed Under: C++
2d Vectors Featured Image

Also referred to as vector of vectors, 2D vectors in C++ form the basis of creating matrices, tables, or any other structures, dynamically. Before arriving on the topic of 2D vectors in C++, it is advised to go through the tutorial of using single-dimensional vectors in C++.

Including the Vector header file

It would be impossible for us to use vectors in C++, if not for the header files that are included at the beginning of the program. To make use of 2D vectors, we include:

#include<vector>

Instead of including numerous kinds of Standard Template Libraries (STL) one by one, we can include all of them by:

#include<bits/stdc++.h>

Initializing 2D vectors in C++

Firstly, we will learn certain ways of initializing a 2-D vector. The following code snippet explains the initialization of a 2-D vector when all the elements are already known.

#include<iostream>
#include<vector>
using namespace std;

int main(){
	vector<vector<int>> v {{1, 0, 1}, {0, 1}, {1, 0, 1}}; 
	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}					   
}

After running the above code, we get the following output:

1 0 1 
0 1 
1 0 1 

The use of 'vector<vector<>>' symbolizes that we are working on a vector of vectors. Each value inside the first set of braces, like '{1, 0, 1}' and '{0, 1}' are vectors independently.

Note: To create 2D vectors in C++ of different data-type, we can place the data-type inside the innermost angle brackets like <char>.

Since we are working on a two-dimensional data structure, we require two loops for traversing the complete data structure, efficiently. The outer loop moves along the rows, whereas the inner loop traverses the columns.

Note: The 'size()' function provides the number of vectors inside the 2D vector, not the total number of elements inside each individual vectors.

Specifying the size for 2D Vector Initialization

2D vectors can be of large sizes. We can not expect the programmer to feed-in every single value. Therefore, we can initialize a 2-D vector on the basis of the number of rows and columns.

#include<iostream>
#include<vector>
using namespace std;

int main(){
	//Number of columns
	int num_col = 3;

	// Number of rows
	int num_row = 4;

	// Initializing a single row
	vector<int> row(num_col, 0);

	// Initializing the 2-D vector
	vector<vector<int>> v(num_row, row) ;

	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}					   
}

The output would be:

0 0 0 
0 0 0 
0 0 0 
0 0 0 

According to the standard initialization of a vector,'vector<int> v(10, 0)', the first argument denotes the size of the vector whereas the second denotes the default value every cell holds.

In the above code snippet, we follow two steps of standard initialization:

  • 'vector<int> row(num_col, 0)' – In this statement, we create a single-dimensional vector called 'row', which has length defined by 'num_col' and default values as '0'. It basically forms each row of our two-dimensional vector.
  • 'vector<vector<int>> v(num_row, row) – In this statement, we create our complete two-dimensional vector, by defining every value of the 2-D vector as the 'row' created in the last statement.

After understanding the above procedure, we can improve our initialization of 2D vectors in C++ by:

#include<iostream>
#include<vector>
using namespace std;

int main(){
	//Number of columns
	int num_col = 3;

	// Number of rows
	int num_row = 4;

	// Initializing the 2-D vector
	vector<vector<int>> v(num_row, vector<int> (num_col, 0)) ;

	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}					   
}

The above code, will provide the similar output as before, since we are doing the exact same thing, but in a single line of code.

If we remember correctly, the standard initialization looks somewhat like the above one. Creating a two-dimensional vector requires us to set the default value for every element as a single-dimensional vector.

The last method involves creating a 2-D vector without the knowledge of rows or columns. It is done by:

vector<vector<int>> v;

The above declaration creates an empty container capable of storing elements in the form of vectors.


Iterators for 2D vectors

Instead of traversing a 2D vector using indices, C++ has a provision of iterators for every specific STL data structure.

#include<iostream>
#include<vector>
using namespace std;

int main(){

	vector<vector<int>> v {{1, 0, 1}, {0, 1}, {1, 0, 1}}; 

	// Iterator for the 2-D vector
	vector<vector<int>>::iterator it1;

	// Iterator for each vector inside the 2-D vector
	vector<int>::iterator it2;

	// Traversing a 2-D vector using iterators
	for(it1 = v.begin();it1 != v.end();it1++){
		for(it2 = it1->begin();it2 != it1->end();it2++)
			cout<<*it2<<" ";
		cout<<endl;
	}					   
}

Output:

1 0 1 
0 1 
1 0 1 

The iterators come in handy when we use certain operations that require an argument for positioning. The two most used functions returning iterator values are:

  • 'v.begin()' – It returns an iterator to the first vector in a 2-D vector.
  • 'v.end()' – It returns an iterator to the end of the 2-D vector.

Let us look at some operations possible on a 2-D vector.


Adding elements to a 2-D vector

To add elements at the end of a two-dimensional vector, we use 'push_back()' function.

#include<iostream>
#include<vector>
using namespace std;

int main(){

	// Initializing the 2-D vector
	vector<vector<int>> v;

	v.push_back({1, 0, 1});
	v.push_back({0, 1});
	v.push_back({1, 0, 1});

	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}					   
}

Output:

1 0 1 
0 1 
1 0 1 

Since our container is a vector of vectors, it would only make sense to push complete vectors inside it. Therefore, the argument passed inside the 'push_back()' function must be a vector.

Note: 'v[i]' represents a single-dimensional vector. Therefore, if the programmer needs to add elements in a certain vector inside the 2-D vector, he may use 'v[i].push_back(value)'.

To add a complete vector at a specific location, we use the 'insert()' function.

#include<iostream>
#include<vector>
using namespace std;

int main(){

	// Initializing the 2-D vector
	vector<vector<int>> v;

	v.push_back({1, 0, 1});
	v.push_back({0, 1});
	v.push_back({1, 0, 1});

	// Iterator for the 2-D vector
	vector<vector<int>>::iterator it = v.begin();

	// Inserting the vector = {1, 2, 3} as the second vector
	v.insert(it + 1, {1, 2, 3});
				  
	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}				   
}

Output:

1 0 1 
1 2 3 
0 1 
1 0 1 

The 'insert()' function requires a positional argument as an iterator not as an integral index. It is followed by a vector that is supposed to be inserted at the specified location.


Removing elements from 2D vectors in C++

Opposite to the 'push_back()', C++ provides 'pop_back()' function with the duty of removing the last element from the given vector.

In the context of this article, 'pop_back()' function would be responsible for removing the last vector from a 2-D vector.

#include<iostream>
#include<vector>
using namespace std;

int main(){

	// Initializing the 2-D vector
	vector<vector<int>> v ;

	// Adding vectors to the empty 2-D vector
	v.push_back({1, 0, 1});
	v.push_back({0, 1});
	v.push_back({1, 0, 1});

	// Remove the last vector from a 2-D vector
	v.pop_back();
				  
	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}				   
}

Output:

1 0 1 
0 1 

In addition to the 'pop_back()' function, we have an 'erase()' function using which we can remove elements from a specified index.

#include<iostream>
#include<vector>
using namespace std;

int main(){

	// Initializing the 2-D vector
	vector<vector<int>> v ;

	// Pushing vector inside the empty 2-D vector
	v.push_back({1, 0, 1});
	v.push_back({0, 1});
	v.push_back({1, 0, 1});

	// Iterator for the 2-D vector
	vector<vector<int>>::iterator it = v.begin();

	// Remove the second vector from a 2-D vector
	v.erase(it + 1);
				  
	for(int i=0;i<v.size();i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j]<<" ";
		cout<<endl;
	}				   
}

Output:

1 0 1 
1 0 1 

Similar to the 'insert()' function, it requires a positional argument as an iterator. To remove all the vectors from the 2-D vector, 'clear()' function can be used.

The above functions might be enough to get comfortable while using 2-D vectors in C++.


Conclusion

Two-dimensional vectors in C++ are very easy to use, provided that the programmer is aware of the syntax involved. This kind of vector comes in handy when we solve problems related to matrices, graphs, and other two-dimensional objects.

We hope that this tutorial enlightened the reader on the topic of using 2-D vectors. Feel free to comment below for any queries related to the topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages