problem passing 2-D vector to a function

Pages: 12
Jul 20, 2018 at 5:51pm
closed account (E0p9LyTq)
When dealing with 2D vectors I find it easier to first get the sizes -- rows & columns -- and then create the vector with the known sizes. No need to push back user supplied values, use operator[] element access to store values.

1
2
3
4
5
6
7
8
9
10
11
12
   std::cout << "Creating a 2-dimensional vector, enter row size: ";
   unsigned row_size;
   std::cin >> row_size;

   std::cout << "Enter column size: ";
   unsigned 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));

Why unsigned? A container's dimension(s) (size) can't be a negative number. I could have used size_t.

Getting the number of rows and columns is easy then, using the vector's size() operator.
1
2
3
   std::cout << "Let's verify the sizes of the 2D vector....\n";
   std::cout << "The vector has " << aVector.size() << " rows.\n";
   std::cout << "The vector has " << aVector[0].size() << " columns.\n\n";

Passing a 2D vector into a function:
1
2
3
4
5
6
7
8
9
10
11
void Display2DArray(std::vector<std::vector<int>> const& aVec)
{
   for (unsigned rows = 0; rows < aVec.size(); rows++)
   {
      for (unsigned cols = 0; cols < aVec[0].size(); cols++)
      {
         std::cout << aVec[rows][cols] << ' ';
      }
      std::cout << '\n';
   }
}

C++11 added the auto keyword, making it very easy to walk through a 2D vector:
1
2
3
4
5
6
7
8
9
10
11
12
void Display2DArray(std::vector<std::vector<int>> const& aVec)
{
   // an easier method for looping and displaying through a 2D vector
   for (const auto& row_itr : aVec)
   {
      for (const auto& col_itr : row_itr)
      {
         std::cout << col_itr << ' ';
      }
      std::cout << '\n';
   }
}

I personally prefer using templated functions so a vector of any data type can be passed into functions.
1
2
template<typename T>
void Display2DArray(std::vector<std::vector<T>> const&)

Overloading operator<< twice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for (auto const& x : v)
   {
      std::cout << x << ' ';
   }

   return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      std::cout << x << '\n';
   }

   return os;
}

makes displaying a 2D vector as easy as
std::cout << aVector;

Here is the entire test source:
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <vector>
#include <numeric>

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

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v);

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v);

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

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

   std::cout << "Enter column size: ";
   unsigned 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));

   std::cout << "Let's verify the sizes of the 2D vector....\n";
   std::cout << "The vector has " << aVector.size() << " rows.\n";
   std::cout << "The vector has " << aVector[0].size() << " columns.\n\n";

   // display the empty 2D vector
   std::cout << "Displaying the empty 2D vector:\n";
   Display2DArray(aVector);
   std::cout << '\n';

   std::cout << "Initializing the 2D vector with some values....\n";
   // initialize the vector with some values other than zero
   int start = 101;
   int offset = 100;

   for (auto& itr : aVector)  // remember the &!!!!!!!!!!!!!!!!!!!!!
   {
      std::iota(itr.begin(), itr.end(), start);
      start += offset;
   }
   // let's display the filled 2D vector
   std::cout << "Displaying the filled 2D vector:\n";
   std::cout << aVector;
   std::cout << '\n';

   std::cout << "Let's try that again....\nDisplaying the empty 2D vector:\n";
   Display2DArray(aVector);
   std::cout << '\n';

   // create a smaller vector
   std::vector<std::vector<int>> aVec2(2, std::vector<int>(2));

   std::cout << "Let's get some values for a 2 x 2 vector:\n";
   Get2DArrayValues(aVec2);
   std::cout << '\n';


   std::cout << "Let's display the new values:\n";
   std::cout << aVec2;
}

template<typename T>
void Display2DArray(std::vector<std::vector<T>> const& aVec)
{
   for (unsigned rows = 0; rows < aVec.size(); rows++)
   {
      for (unsigned cols = 0; cols < aVec[0].size(); cols++)
      {
         std::cout << aVec[rows][cols] << ' ';
      }
      std::cout << '\n';
   }

   // an easier method for looping and displaying through a 2D vector
   /*for (const auto& row_itr : aVec)
   {
      for (const auto& col_itr : row_itr)
      {
         std::cout << col_itr << ' ';
      }
      std::cout << '\n';
   }*/
}


template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for (auto const& x : v)
   {
      std::cout << x << ' ';
   }

   return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      std::cout << x << '\n';
   }

   return os;
}

template<typename T>
void Get2DArrayValues(std::vector<std::vector<T>>& aVec)
{
   for (size_t rows = 0; rows < aVec.size(); rows++)
   {
      for (size_t cols = 0; cols < aVec[0].size(); cols++)
      {
         std::cout << "[" << rows << "][" << cols << "]: ";
         int input;
         std::cin >> input;
         aVec[rows][cols] = input;
      }
   }
}


This works in Visual Studio 2017 and Code::Blocks.
Creating a 2-dimensional vector, enter row size: 3
Enter column size: 4

Let's verify the sizes of the 2D vector....
The vector has 3 rows.
The vector has 4 columns.

Displaying the empty 2D vector:
0 0 0 0
0 0 0 0
0 0 0 0

Initializing the 2D vector with some values....
Displaying the filled 2D vector:
101 102 103 104
201 202 203 204
301 302 303 304

Let's try that again....
Displaying the empty 2D vector:
101 102 103 104
201 202 203 204
301 302 303 304

Let's get some values for a 2 x 2 vector:
[0][0]: 2
[0][1]: 4
[1][0]: 6
[1][1]: 8

Let's display the new values:
2 4
6 8
Last edited on Jul 21, 2018 at 3:23pm
Jul 21, 2018 at 10:52am
thanks a lot ...can you help me with debugging on code blocks...i cannot debug, i get error message while using containers like vector in code
Jul 22, 2018 at 3:54pm
closed account (E0p9LyTq)
A couple of things stand out that can be a major stumbling block to helping you:

1. No comments. You know what the code you posted is supposed to do, I don't have much of a clue.

2. Using single character variable names. What are they for? Single character variable names by convention should only be used in simple loops, not everywhere as you've done.

Good variable names go a long way to self-documenting your code.

3. Your request for inputs. No text "markers" to inform the user what they should enter.

If you want help with your code, write it so it can be understood by others.

More than once I've looked at older code I worked on months and years ago and set aside. Now it looks like something others have written. I don't remember why I wrote something a certain way if I didn't document it.

I made some wild guesses as to what your code was doing, lack of documentation didn't help. The following for me works, but it may or may not be what you want it to do:
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <vector>
#include <cctype> // for toupper()

void Takeinput(std::vector<std::vector<int>>& arr)
{
   for (size_t rows = 0; rows < arr.size(); rows++)
   {
      for (size_t cols = 0; cols < arr[0].size(); cols++)
      {
         std::cout << "[" << rows << "][" << cols << "]: ";
         int input;
         std::cin >> input;

         arr[rows][cols] = input;
      }
   }
}

int Sum(std::vector<std::vector<int>>& arrA, std::vector<std::vector<int>>& arrB)
{
   int sum    = 0;
   int sum1   = 0;
   int sum2   = 0;
   unsigned i = 0;

   while (i < arrA.size())
   {
      for (unsigned j = 0; j < arrA.size(); j++)
      {
         sum  = sum + arrA[i][j];
         sum1 = sum + arrB[j][i];
      }

      i++;

      sum2 = sum2 + sum * sum1;
      sum  = 0;
      sum1 = 0;
   }

   return sum2;
}

int main()
{
   std::cout << "Enter the dimension of the square vector: ";
   int N;
   std::cin >> N;

   //  create the vector and THEN pass it to your function
   std::vector<std::vector<int>> arrA(N, std::vector<int>(N));

   std::cout << "Enter the values for the first 2D vector:\n";
   Takeinput(arrA);

   std::vector<std::vector<int>> arrB(N, std::vector<int>(N));

   std::cout << "Enter the values for the second 2D vector:\n";
   Takeinput(arrB);

   // what does this input do?  Use a text "label" so the user knows what to enter and why.
   int Q;
   std::cin >> Q;

   while (Q--)
   {
      // the following inputs are somewhat easier to understand without any documentation, but
      // better variable names and/or some comments could be very helpful
      char ch;
      std::cin >> ch;

      int a, b, c;
      std::cin >> a >> b >> c;

      // I used the toupper() function so it doesn't matter whether the user entered upper or lower case
      // http://www.cplusplus.com/reference/cctype/toupper/
      if (toupper(ch) == 'A')
      {
         arrA[a][b] = c;
      }
      else
      {
         arrB[a][b] = c;
      }

      std::cout << "The sum of the two 2D vectors is: ";
      std::cout << Sum(arrA, arrB) << ".\n";
   }
}

Enter the dimension of the square vector: 2
Enter the values for the first 2D vector:
[0][0]: 2
[0][1]: 4
[1][0]: 6
[1][1]: 8
Enter the values for the second 2D vector:
[0][0]: 4
[0][1]: 8
[1][0]: 12
[1][1]: 24
1
a 1
2
3
The sum of the two 2D vectors is: 640.
Last edited on Jul 22, 2018 at 3:57pm
Jul 22, 2018 at 5:27pm
@FurryGuy,
this looks like a challenge from codechef or sth. similar.
Input comes from a file that gets redirected to cin so you don't use prompts.
Actually writing prompts would actually gets the wrong output.
Usually people take the one-char variable names directly from the task.
Jul 23, 2018 at 10:47am
thanks a lot ...can you help me with debugging on code blocks...i cannot debug, i get error message while using containers like vector in code


People in this thread have already asked you to tell us the details of what those error messages say. Why are you refusing to do so? How can we help you, if you refuse to give us the information we need to help you?
Topic archived. No new replies allowed.
Pages: 12