Two Dimensional Vectors

I just learned about two a dimensional vector, and filled it with the 12 times table as an exercise to practice with. I got it to work. However, I am curious if it can be done more efficiently. I currently have else if statements for each of the 12 rows, and perform a calculation that counts by 1, 2, 3, 4, . . . Is it possible to come up with an algorithm that can handle this without all these separate conditions?

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
71
72
73
74
75
76
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	
	vector< vector<int> > grid(12, vector<int>(12)); 
	
	for (int row = 0; row < grid.size(); row++) {
		for (int col = 0; col < grid[row].size(); col++) {
			
			if (row == 0) {
				grid[row].at(col) = col + 1;
			}

			else if (row == 1) {
				int countByTwo = 2 * (col + 1);
				grid[row].at(col) = countByTwo;
			}

			else if (row == 2) {				
				int countByThree = 3 * (col + 1);
				grid[row].at(col) = countByThree;			
			}

			else if (row == 3) {
				int countByFours = 4 * (col + 1);
				grid[row].at(col) = countByFours;
			}

			else if (row == 4) {
				int countByFives = 5 * (col + 1);
				grid[row].at(col) = countByFives;
			}

			else if (row == 5) {
				int countBySix = 6 * (col + 1);
				grid[row].at(col) = countBySix;
			}

			else if (row == 6) {
				int countBySeven = 7 * (col + 1);
				grid[row].at(col) = countBySeven;
			}

			else if (row == 7) {
				int countByEight = 8 * (col + 1);
				grid[row].at(col) = countByEight;
			}

			else if (row == 8) {
				int countByNine = 9 * (col + 1);
				grid[row].at(col) = countByNine;
			}

			else if (row == 9) {
				int countByTen = 10 * (col + 1);
				grid[row].at(col) = countByTen;
			}

			else if (row == 10) {
				int countByEleven = 11 * (col + 1);
				grid[row].at(col) = countByEleven;
			}

			else if (row == 11) {
				int countByTwelve = 12 * (col + 1);
				grid[row].at(col) = countByTwelve;
			}

			cout << " " << grid[row][col] << flush;
		}
		cout << endl;
	}
}
Like
grid[row].at(col) = (row+1)*(col+1);
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
#include <iostream>
#include <vector>

int main()
{
    
    std::vector<std::vector<int>> table;
    
    table.resize(13, std::vector<int>(13) );
    
    for(int row = 1; row <= 12; row++)
    {
        for(int col = 1; col <= 12; col++)
        {
            table[row][col] = row * col;
        }
    }
    
    // 3 TIMES TABLE
    for (int i = 1; i < 13; i++)
        std::cout << table[i][3] << '\n';
    
    std::cout << '\n';
    
    
    // OOP's FORGOT IT IS ABOUT THE WHOLE TABLE
    for(int row = 1; row <= 12; row++)
    {
        for(int col = 1; col <= 12; col++)
        {
            std::cout << table[row][col] << '\t';
        }
        std::cout << '\n';
    }
    
    return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
#include <valarray>
#include <numeric>
using namespace std;

int main()
{
   valarray< valarray<int> > grid(valarray<int>(12),12);
   iota( begin( grid[0]), end( grid[0] ), 1 );
   for ( int i = 1; i < 12; i++ ) grid[i] = grid[i-1] + grid[0];
   for ( auto &row : grid )
   {
      for ( auto e : row ) cout << setw( 3 ) << e << " ";
      cout << '\n';
   }
}






  1   2   3   4   5   6   7   8   9  10  11  12 
  2   4   6   8  10  12  14  16  18  20  22  24 
  3   6   9  12  15  18  21  24  27  30  33  36 
  4   8  12  16  20  24  28  32  36  40  44  48 
  5  10  15  20  25  30  35  40  45  50  55  60 
  6  12  18  24  30  36  42  48  54  60  66  72 
  7  14  21  28  35  42  49  56  63  70  77  84 
  8  16  24  32  40  48  56  64  72  80  88  96 
  9  18  27  36  45  54  63  72  81  90  99 108 
 10  20  30  40  50  60  70  80  90 100 110 120 
 11  22  33  44  55  66  77  88  99 110 121 132 
 12  24  36  48  60  72  84  96 108 120 132 144
Last edited on
Looking at your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
			if (row == 0) {
				grid[row].at(col) = col + 1;
			}

			else if (row == 1) {
				int countByTwo = 2 * (col + 1);
				grid[row].at(col) = countByTwo;
			}

			else if (row == 2) {				
				int countByThree = 3 * (col + 1);
				grid[row].at(col) = countByThree;			
			}

You have a temporary variable in each branch (except the first) and it has different name each time.
While this does document the code, its added value is low. Lets be more systematic:
1
2
3
4
5
6
7
8
9
10
11
12
if (row == 0) {
  int product = col + 1;
  grid[row].at(col) = product;
}
else if (row == 1) {
  int product = 2 * (col + 1);
  grid[row].at(col) = product;
}
else if (row == 2) {				
  int product = 3 * (col + 1);
  grid[row].at(col) = product;
}

The first case is still different from the rest. Lets be more explicit with it:
1
2
3
4
if (row == 0) {
  int product = 1 * (col + 1);
  grid[row].at(col) = product;
}

Now every case has a body similar to:
1
2
  int product = N * (col + 1);
  grid[row].at(col) = product;

Looking at all the cases, you should notice that in every case row + 1 == N
This leads to the:
1
2
3
4
5
6
for (int row = 0; row < grid.size(); row++) {
  for (int col = 0; col < grid[row].size(); col++) {
    int product = (row + 1) * (col + 1);
    grid[row].at(col) = product;
  }
}


Vector has two member access methods: operator[] and function at(). The latter checks that index is valid and is thus usually slower, but safer.
You use a mixture.
If you want to play it safe, then use at() for both vectors:
grid.at(row).at(col) = product;
If you trust your indexing, then use [] for both:
grid[row][col] = product;


againtry wrote:
1
2
    std::vector<std::vector<int>> table;
    table.resize(13, std::vector<int>(13) );

Vector has fill constructor (which stoneJax was already using). In your example:
std::vector<std::vector<int>> table(13, std::vector<int>(13) );
Last edited on
Vector has fill constructor (which stoneJax was already using). In your example:
std::vector<std::vector<int>> table(13, std::vector<int>(13) );
Is there a point to this quote?.
Is there a point to use resize rather than constructor, in this case?
I appreciate everyone's examples. Definitely much more efficient.

keskiverto, your demonstration of how my code leads to a single equation that can be used on one line is very clear. Also, thanks for pointing out the differences between using [] and .at(); I didn't think about that.
Topic archived. No new replies allowed.