copy 2d vector into new 2d vector

Jun 8, 2020 at 10:21am
Hi everyone.. I'm new to C++.. I'm here seeking for some advise.. I got a problem in copying 2d vector (populationP) into new 2d vector (populationP1_shortR). Hoping someone can help me. Thank you :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
double shortR_proportional = 0.1;
vector<vector<int>> populationP1_shortR;

for (size_t i = 0; i < population_size; i++)
{
    if (shortR_proportional >= mappingfitnessNX[i])
    {
	cout << "Found at route [" << route_id[i] << "]: "
	<< mappingfitnessNX[i]
	<< "\n";

	cout << "Route: " << "\n";
	for (size_t j = 0; j < populationP[i].size(); j++)
	{
 	    cout << populationP[i][j] << "  ";
	    populationP1_shortR.push_back(populationP);
        }
	cout << endl;
    }
}
Jun 8, 2020 at 11:05am
1
2
3
4
5
	for (size_t j = 0; j < populationP[i].size(); j++)
	{
 	    cout << populationP[i][j] << "  ";
	    populationP1_shortR.push_back(populationP);
        }

Shouldn't this just be
populationP1_shortR.push_back(populationP[i]);

Jun 8, 2020 at 1:05pm
would it be better to just assign them?
1
2
3
4
5
6
populationP1_shortR = populationP;
and if you need to print it, do that on the side:
for (size_t j = 0; j < populationP[i].size(); j++)
	{
 	    cout << populationP[i][j] << "  ";
        }
Jun 8, 2020 at 3:08pm
There are several ways to copy an entire 2D vector to a new 2D vector. One method is to use indexing on the outer vector and push back the entire inner vector into the new 2D vector:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   // create a 2D vector, and fill with some values
   std::vector<std::vector<int>> vec1;
   vec1 = {{ 1, 2, 3 },
           { 4, 5, 6, 107, 14 },
           { 7, 8, 9 },
           { 10, 11, 12 }};

   // copy the entire 2D vector into a new 2D vector using indexing
   std::vector<std::vector<int>> vec2;

   for (size_t i { }; i < vec1.size(); i++)
   {
      vec2.push_back(vec1.at(i));
   }

You can simply assign the 2D vector:
1
2
3
4
   // create a new 2D vector
   std::vector<std::vector<int>> vec3;
   // assign the old vector
   vec3 = vec1;

C++11 has a new form of assignment, uniform initialization:
1
2
   // create a new 2D vector using direct assignment (uniform initialization)
   std::vector<std::vector<int>> vec4 { vec1 };

Uniform initialization could make creating the initial vector something like this:
1
2
3
4
5
   // create a 2D vector, and fill with some values
   std::vector<std::vector<int>> vec1 {{ 1, 2, 3 },
                                       { 4, 5, 6, 107, 14 },
                                       { 7, 8, 9 },
                                       { 10, 11, 12 }};


There are a couple of different ways to display the contents of a 2D vector, using indexing:
1
2
3
4
5
6
7
8
9
   // display the 2D vector using indexing
   for (size_t i { }; i < vec1.size(); i++)
   {
      for (size_t j { }; j < vec1.at(i).size(); j++)
      {
         std::cout << vec1.at(i).at(j) << ' ';
      }
      std::cout << '\n';
   }

Another is using range-based for loops. This method makes it virtually impossible to go out of bounds:
1
2
3
4
5
6
7
8
9
   // display the 2D vector using range-based for loops
   for (const auto& itr1 : vec2)
   {
      for (const auto& itr2 : itr1)
      {
         std::cout << itr2 << ' ';
      }
      std::cout << '\n';
   }


Adapting one or the other output method to a function (range-based example):
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
#include <iostream>
#include <vector>

void printVec(const std::vector<std::vector<int>>&);

int main()
{
   // create a 2D vector, and fill with some values
   std::vector<std::vector<int>> vec { { 1, 2, 3 },
                                       { 4, 5, 6, 107, 14 },
                                       { 7, 8, 9 },
                                       { 10, 11, 12 } };

   // display the 2D vector using a function
   printVec(vec);
}

void printVec(const std::vector<std::vector<int>>& vec)
{
   for (const auto& itr : vec)
   {
      for (const auto& itr2 : itr)
      {
         std::cout << itr2 << ' ';
      }
      std::cout << '\n';
   }
}


A more advanced method is to overload the std::ostream operator<< so displaying a 1D, 2D or even a 3D vector is as easy as:
std::cout << vec << '\n';

I've already thrown a lot of possible new concepts and ideas at your already. Showing how to overload operator<< can wait. :)

Why do I use at() instead of [] for the indexing? Using at() makes it obvious if the indexing goes out of bounds. The program crashes. Going out of bounds is a very serious error with a container.
Jun 9, 2020 at 12:30am
Thank you everyone for your advise. Really appreciated it :)
Topic archived. No new replies allowed.