Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to split a vector into two smaller arrays?

What I'm trying to do:

I am trying to split a vector into two separate arrays. The current int vector contains an element per line in a text file. The text file is a list of random integers.

How I'm planning to do it:

My current idea is to create two regular int arrays, then iterate over the entire vector and copy n/2 elements to each of the arrays.

What I would like to know:

What is the most elegant way of accomplishing my task? I have a feeling that I can do this without iterating over the vector multiple times.

Code:

#include <vector> #include <fstream> #include <iterator> #include <iostream> using namespace std;  vector<int> ifstream_lines(ifstream& fs) {   vector<int> out;   int temp;   while(fs >> temp)   {     out.push_back(temp);   }   return out; }  vector<int> MergeSort(vector<int>& lines) {   int split = lines.size() / 2;   int arrayA[split];   int arrayB[split]; }  int main(void)  {   ifstream fs("textfile.txt");   vector<int> lines;   lines = ifstream_lines(fs);    return 0; } 

Thank you :)

like image 326
mightcouldb1 Avatar asked Mar 21 '12 19:03

mightcouldb1


2 Answers

Use iterators.

std::vector<int> lines; // fill std::size_t const half_size = lines.size() / 2; std::vector<int> split_lo(lines.begin(), lines.begin() + half_size); std::vector<int> split_hi(lines.begin() + half_size, lines.end()); 

Since iterator ranges represent half open ranges [begin, end), you don't need to add 1 to the second begin iterator: lines.begin() + half_size isn't copied to the first vector.


Note that things like

int split = lines.size() / 2; int arrayA[split]; int arrayB[split]; 

Are not standard C++ (and as such not portable). These are so-called variable-length arrays (VLAs for short) and are a C99 thing. Some compilers have them as an extension while compiling C++ code (GCC, Clang). Always compile with -pedantic to get a warning. These VLAs act funky for non-POD types and aren't generally useful, since you can't even return them.

like image 182
Xeo Avatar answered Sep 29 '22 10:09

Xeo


If you can't use code from Xeo answer due to strict compiler rules or you want more generic way, try std::advance:

#include <vector> #include <iterator>  size_t middle = input.size()/2; std::vector<int>::const_iterator middleIter(input.cbegin()); std::advance(middleIter, middle);  std::vector<int> leftHalf(input.begin(), middleIter); std::vector<int> rightHalf(middleIter, input.end()); 
like image 39
iamantony Avatar answered Sep 29 '22 12:09

iamantony