split vector

Hi everyone. I need some advice. How can i split the following vector. For example, row 1 until 10 will be in first column and row 11 until row 20 will be in second column.

I have a vector (namely as new_obj_function):
246.187
223.655
221.221
208.876
208.805
208.725
207.946
206.678
202.659
185.133
246.072
244.842
223.49
210.24
215.256
246.259
246.945
245.677
252.333
208.988

I need to split it into 2d vector (10 value for each column) as follow:
246.187 246.072
223.655 244.842
221.221 223.49
208.876 210.24
208.805 215.256
208.725 246.259
207.946 246.945
206.678 245.677
202.659 252.333
185.133 208.988

But, after code it. I got a wrong solution as follow:
246.187 223.655
221.221 208.876
208.805 208.725
207.946 206.678
202.659 185.133
246.072 244.842
223.49 210.24
215.256 246.259
246.945 245.677
252.333 208.988

I need advice from you guys. How can I fix it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Create a vector that contains n generations of total distance @ Z-value
	vector<vector<double>> new_total_distance(population_size);

	for (size_t i = 0; i < population_size; i++) 
	{
		// Get the i-th inner vector from the outer vector and fill it
		vector<double> & inner_vector = new_total_distance[i];
		for (size_t j = 0; j < generation; j++) 
		{
			inner_vector.push_back(new_obj_function[generation * i + j]);
		}
	}

	for (size_t i = 0; i < new_total_distance.size(); i++)
	{
		for (size_t j = 0; j < new_total_distance[i].size(); j++)
		{
			cout << new_total_distance[i][j] << "	";
		}
		cout << "\n";
	}
	cout << "\n";
preallocate the new one so it has space up front and then

for(i = 0; i < 10; i++)
{
new_total_distance[i][0] = orig[i];
new_total_distance[i][1] = orig[i+10];
}
Last edited on
Hi jonnin,

can you use span() and subspan()?

Is there others simple way to do it?

For example I have 10 values here:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10

I need split or divide it into 2 column as follow:
1 6
2 7
3 8
4 9
5 10
Do you actually need to split the vector's data, or is printing as two separate columns enough?
I need to split the vector data for me to do the next process. But when I split it I got wrong solution.
I didn't feel like making a compileable example out of your incomplete code, so I just re-wrote it myself:

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
#include <iostream>
#include <vector>

int main()
{
    using namespace std;
    using Column = std::vector<double>;
    
    const size_t num_columns = 2;
    
    vector<double> raw_data { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    size_t size_per_column = raw_data.size() / num_columns; // 10 / 2 == 5
    vector<Column> columned_data(num_columns,
        vector<double>(size_per_column));
        
    for (size_t i = 0; i < num_columns; i++)
    {
        for (size_t j = 0; j < size_per_column; j++)
        {
            columned_data[i][j] = raw_data[i * size_per_column + j];
        }          
    }

    for (size_t j = 0; j < size_per_column; j++)
    {
        for (size_t i = 0; i < num_columns; i++)
        {
            // (would be more efficient to print each column together)
            cout << columned_data[i][j] << ' ';
        }
        cout << '\n';
    }
}

1 6
2 7
3 8
4 9
5 10


Assumes the number of columns divides the number of elements in the raw data.

Perhaps that can help. I don't see an obvious problem with your original post's code excerpt, but like I said I didn't attempt to run it since I couldn't.
Last edited on
std::copy in <algorithm> can also be used, using 'pointer math' on vector iterators:
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
#include <iostream>
#include <vector>
#include <numeric>   // std::iota
#include <algorithm> // std::copy

int main()
{
   std::vector<int> orig_vec(20);

   // fill the original vector with values from 1 - 20
   // just for testing
   std::iota(orig_vec.begin(), orig_vec.end(), 1);

   std::vector<int> vec1(10);
   std::vector<int> vec2(10);

   std::copy(orig_vec.begin(), orig_vec.begin() + 10, vec1.begin());
   std::copy(orig_vec.begin() + 10, orig_vec.end(), vec2.begin());

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

   for (const auto& itr : vec2)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';
}
1 2 3 4 5 6 7 8 9 10

11 12 13 14 15 16 17 18 19 20

You could split the original vector into odd /even vector using std::copy_if (with the help of a lambda). Change lines 17-18 to:
17
18
   std::copy_if(orig_vec.begin(), orig_vec.end(), vec1.begin(), [] (int i) { return (i % 2 != 0); });
   std::copy_if(orig_vec.begin(), orig_vec.end(), vec2.begin(), [] (int i) { return (i % 2 == 0); });
1 3 5 7 9 11 13 15 17 19

2 4 6 8 10 12 14 16 18 20
simpler than what I gave?! ... its two lines..

for(i = 0; i < 10; i++)
{
new_total_distance[i][0] = orig[i];
new_total_distance[i][1] = orig[i+10];
}
Hi jonnin,
simpler than what I gave?! ... its two lines..

Sorry. I thought it was about your previous edited comment which are span() and subspan().
Btw, thank you for your help. Really appreciated it.. :)

Same goes to Ganado and Furry Guy,
Thank you for help. Much appreciated :)
Last edited on
Topic archived. No new replies allowed.