Dynamic Arrays using std::vector

# Using Vector for a 2D Grid

## How can I use std::vector to implement a simple 2D grid or matrix?

Using std::vector to implement a 2D grid or matrix is a common and efficient way to handle two-dimensional data in C++. There are primarily two approaches: using a vector of vectors, or using a single vector with customÂ indexing.

## Approach 1: Vector of Vectors

This is the most straightforward approach, where we create a vector of vectorÂ elements:

#include <iostream>
#include <vector>

class Grid {
private:
std::vector<std::vector<int>> data;
size_t rows, cols;

public:
Grid(size_t r, size_t c)
: rows(r), cols(c),
data(r, std::vector<int>(c, 0)){}

int& at(size_t r, size_t c){
return data[r][c];
}

const int& at(size_t r, size_t c) const{
return data[r][c];
}

void print() const{
for (const auto& row : data) {
for (int val : row) {
std::cout << val << ' ';
}
std::cout << '\n';
}
}
};

int main(){
Grid grid(3, 4);

// Set some values
grid.at(0, 0) = 1;
grid.at(1, 2) = 5;
grid.at(2, 3) = 9;

// Print the grid
grid.print();
}
1 0 0 0
0 0 5 0
0 0 0 9

This approach is intuitive and allows for rows of different lengths if needed. However, it may have slightly more overhead due to multipleÂ allocations.

## Approach 2: Single Vector with Custom Indexing

This approach uses a single vector to store all elements, which can be moreÂ efficient:

#include <iostream>
#include <vector>

class Grid {
private:
std::vector<int> data;
size_t rows, cols;

public:
Grid(size_t r, size_t c)
: rows(r), cols(c), data(r * c, 0){}

int& at(size_t r, size_t c){
return data[r * cols + c];
}

const int& at(size_t r, size_t c) const{
return data[r * cols + c];
}

void print() const{
for (size_t i = 0; i < rows; ++i) {
for (size_t j = 0; j < cols; ++j) {
std::cout << at(i, j) << ' ';
}
std::cout << '\n';
}
}
};

int main(){
Grid grid(3, 4);

// Set some values
grid.at(0, 0) = 1;
grid.at(1, 2) = 5;
grid.at(2, 3) = 9;

// Print the grid
grid.print();
}
1 0 0 0
0 0 5 0
0 0 0 9

This approach uses a single allocation and can be more cache-friendly, potentially offering better performance for largeÂ grids.

You can extend either approach with more advancedÂ features:

### Range Checking

Add bounds checking in the at()Â function:

int& at(size_t r, size_t c){
if (r >= rows || c >= cols) {
throw std::out_of_range(
"Grid indices out of range");
}
return data[r * cols + c];
}

### Iterators

Implement custom iterators for row-wise or column-wiseÂ traversal.

### Resizing

Add functions to resize theÂ grid:

void resize(size_t new_rows, size_t new_cols){
std::vector<int> new_data(
new_rows * new_cols, 0);
for (size_t i = 0; i <
std::min(rows, new_rows); ++i) {
for (size_t j = 0; j <
std::min(cols, new_cols); ++j) {
new_data[i * new_cols + j] = at(i, j);
}
}
data = std::move(new_data);
rows = new_rows;
cols = new_cols;
}

### Operations

Implement mathematical operations like matrix addition orÂ multiplication.

Remember, the choice between these approaches depends on your specific use case. The vector of vectors is more flexible but might be slightly slower, while the single vector approach is generally faster but less flexible for non-rectangularÂ grids.

This Question is from the Lesson:

### Dynamic Arrays using std::vector

Explore the fundamentals of dynamic arrays with an introduction to std::vector

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

### Dynamic Arrays using std::vector

Explore the fundamentals of dynamic arrays with an introduction to std::vector

Part of the course:

## Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

### This course includes:

• 57 Lessons
• Over 200 Quiz Questions
• 95% Positive Reviews
• Regularly Updated
• Help and FAQ
Free, Unlimited Access

### Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.