2D vector

I'm making a 2D vector for a memory match game, the user input defines the size with variables rows and columns. The following code is only how the 2D vector is populated, there is a separate function that prints the vector.
1
2
3
4
5
6
7
8
  std::vector<std::vector<int>> board;
	for(int i = 0; i < rows; i++){
		std::vector<int> temp;
		for(int j = 0; j < columns; j++){
			temp.push_back(j + 1);
		}
		board.push_back(temp);
	}


If the user were to input 4 rows and 5 columns, the output would be:

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

How would I get it to print:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
Change line 5 above to:
 
           temp.push_back(i * columns + j + 1);

Thanks so much, works perfectly now
closed account (E0p9LyTq)
std::vector can be created several different ways:
http://www.cplusplus.com/reference/vector/vector/vector/

Creating a known size vector (default filled with zeros for numeric values):
1
2
// creating a sized vector
std::vector<int> aVec(5);

Creating a sized vector with a non-default value:
1
2
// creating a sized vector filled with a value other than zero
std::vector<int> aVec2(5, 100);

With a vector sized on creation there is no need to push_back, you can access elements directly right after creating the vector:
1
2
3
4
5
for (int itr = 0; itr < aVec.size(); itr++)
{
   std::cout << aVec[itr] << ' ';
}
std::cout << '\n';

Creating a true 2D vector is not hard:
1
2
3
4
5
6
7
8
9
10
std::cout << "Creating a 2-dimensional vector, enter row size: ";
int row_size;
std::cin >> row_size;

std::cout << "Enter column size: ";
int col_size;
std::cin >> col_size;

// create a 2 dimensional int vector with known dimensions
std::vector<std::vector<int>> aVector(row_size, std::vector<int>(col_size));

Normally when passing an array as a function parameter the size of the array must also be passed. With std::vector there is no need, the vector keeps track of its size.

I use a templated function so I can use one function for different type vectors. Passing a 2D vector is easy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename T>
void Print2DVector(std::vector<std::vector<T>> const& aVec)
{
   int row_size = aVec.size();
   int col_size = aVec[0].size();

   for (int row_loop = 0; row_loop < row_size; row_loop++)
   {
      for (int col_loop = 0; col_loop < col_size; col_loop++)
      {
         // let's display the filled 2D vector
         std::cout << aVec[row_loop][col_loop] << ' ';
      }
      std::cout << '\n';
   }
}

This function will print 2D vectors of a single POD type. int, double, float, char, etc.

The advantages of dealing with a true 2D vector outweighs IMO the not-as-easy way of constructing one compared to a 2D array. Especially useful is being able to create a 2D vector at runtime without having to muck around with manually allocating memory.

Putting the example together:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <vector>

template<typename T>
void Print2DVector(std::vector<std::vector<T>> const&);

int main()
{
   // creating a sized vector
   std::vector<int> aVec(5);
   std::cout << aVec.size() << '\n';

   for (int itr = 0; itr < aVec.size(); itr++)
   {
      std::cout << aVec[itr] << ' ';
   }
   std::cout << "\n\n";

   // creating a sized vector filled with a value other than zero
   std::vector<int> aVec2(5, 100);
   std::cout << aVec2.size() << '\n';

   for (auto itr : aVec2)
   {
      std::cout << itr << ' ';
   }
   std::cout << "\n\n";

   std::cout << "Creating a 2-dimensional vector, enter row size: ";
   int row_size;
   std::cin >> row_size;

   std::cout << "Enter column size: ";
   int col_size;
   std::cin >> col_size;

   std::cout << "\n";

   // create a 2 dimensional int vector with known dimensions
   std::vector<std::vector<int>> aVector(row_size, std::vector<int>(col_size));

   // initialize the vector with some values other than zero
   for (int row_loop = 0; row_loop < row_size; row_loop++)
   {
      for (int col_loop = 0; col_loop < col_size; col_loop++)
      {
         aVector[row_loop][col_loop] = (((row_loop + 1) * 100) + col_loop + 1);
      }
   }

   // let's display the filled 2D vector
   Print2DVector(aVector);
}

template<typename T>
void Print2DVector(std::vector<std::vector<T>> const& aVec)
{
   int row_size = aVec.size();
   int col_size = aVec[0].size();

   for (int row_loop = 0; row_loop < row_size; row_loop++)
   {
      for (int col_loop = 0; col_loop < col_size; col_loop++)
      {
         // let's display the filled 2D vector
         std::cout << aVec[row_loop][col_loop] << ' ';
      }
      std::cout << '\n';
   }
}

5
0 0 0 0 0

5
100 100 100 100 100

Creating a 2-dimensional vector, enter row size: 3
Enter column size: 5

101 102 103 104 105
201 202 203 204 205
301 302 303 304 305


Hello,
how about declaring and initialising a vector of known dimensions with known values a la :

std::vector<std::vector<int>> myvect ( 2, std::vector<int>(9))
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, { 9, 10, 11, 12, 13, 14, 15, 16, 17 } };
the declaring looks ok but the defining brings out this compiler error :
abase.cpp:8:1: error: expected ‘,’ or ‘;’ before ‘{’ token
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8 },

closed account (E0p9LyTq)
how about declaring and initialising a vector of known dimensions with known values

The initializer list provides the 2D dimensions, each row can have differing column sizes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>

int main()
{
   std::vector<std::vector<int>> myvect { { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
                                          { 9, 10, 11, 12, 13 },
                                          { 14, 15, 16, 17, 18, 19, 20 } };

   for (size_t row_loop = 0; row_loop < myvect.size(); row_loop++)
   {
      for (size_t col_loop = 0; col_loop < myvect[row_loop].size(); col_loop++)
      {
         std::cout << myvect[row_loop][col_loop] << '\t';
      }
      std::cout << '\n';
   }
}

0       1       2       3       4       5       6       7       8
9       10      11      12      13
14      15      16      17      18      19      20
Last edited on
Just wanted to showcase our good friend std::iota , from <numeric> header.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <numeric>
#include <vector>

using namespace std;

void Show(const vector<vector<int>>& v)
{
    for(auto& row : v)
    {
        for (auto& ele : row)
            cout << ele << " ";
        cout << endl;
    }
}

int main() 
{
    // Dynamic, e.g. user-input values
    int rows = 4;
    int cols = 5;
    
    int start = 11;    // Value of first element in row
    int offset = 20;   // Offset of starting values between rows
    vector<vector<int>> board(rows, vector<int>(cols));
    for(auto& row : board)
    {
        iota(row.begin(), row.end(), start);
        start += offset;
    }
    Show(board);
    
}

11 12 13 14 15 
31 32 33 34 35 
51 52 53 54 55 
71 72 73 74 75


Edit: I should also note that the board can alternately be populated by pushing back one row at a time:
1
2
3
4
5
6
7
8
9
vector<vector<int>> board;
board.reserve(rows);
for(int x=1; x<=rows; ++x)
{
    vector<int> row(cols);
    iota(row.begin(), row.end(), start);
    board.emplace_back(row);
    start += offset;
}
Last edited on
closed account (E0p9LyTq)
@icy,

I was curious if a 2D vector would work with range-based for loops. Your range-based for loop to fill the 2D vector made me rethink my output function:

1
2
3
4
5
6
7
8
9
10
11
12
template<typename T>
void Print2DArray(std::vector<std::vector<T>> const& aVec)
{
   for (const auto& row_itr : aVec)
   {
      for (const auto& col_itr : row_itr)
      {
         std::cout << col_itr << ' ';
      }
      std::cout << '\n';
   }
}

Thanks for the assist. :)

One step further; the vector does not have to be 2D, even though you will print "2D board":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <numeric>
#include <vector>

void Show( const std::vector<int>& v, size_t COLS )
{
    for ( size_t i=0; i < v.size(); ++i )
    {
        std::cout << v[i] << " ";
        if ( 0 == (i+1) % COLS ) std::cout << '\n';
    }
}

int main() 
{
    size_t rows = 4;
    size_t cols = 5;    
    std::vector<int> board( rows*cols );
    std::iota( board.begin(), board.end(), 13 );
    Show( board, cols );
}

13 14 15 16 17 
18 19 20 21 22 
23 24 25 26 27 
28 29 30 31 32 
Topic archived. No new replies allowed.