Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to concatenate/merge vectors

Tags:

c++

vector

I'm trying to figure out a way to merge 2 vectors and an integer into one vector. ie

return data.push_back(fn(data1), mid, fn(data2));

NB This is a recursive function. The vector data has values stored in it before it reaches the return statement. I need the values in data to be updated with the values in the return statement.

I have absolutely no idea how to go about doing this. I've been searching for a couple of hours, but nothing seems to work!

Any guidance is very much appreciated.

like image 278
CocaCola Avatar asked Dec 16 '22 18:12

CocaCola


1 Answers

std::vector::insert() accepts an iterator range:

std::vector<int> left(fn(data1));
std::vector<int> right(fn(data2));
data.insert(data.end(), left.begin(), left.end());
data.push_back(mid);
data.insert(data.end(), right.begin(), right.end());
return data;

You can also use std::copy() from <algorithm> and std::back_inserter() from <iterator>:

std::copy(left.begin(), left.end(), std::back_inserter(data));
data.push_back(mid);
std::copy(right.begin(), right.end(), std::back_inserter(data));

However, insert() can know the size of its input range in advance and reserve() the appropriate amount of memory, while back_insert_iterator is opaque—it just repeatedly calls push_back(). They both run in linear time, but insert() will probably make fewer allocations.

If the elements of your vectors are more efficient to move than to copy, you can use the C++11 std::make_move_iterator() from <iterator> to adapt the input ranges:

data.insert(data.end(),
    std::make_move_iterator(left.begin()),
    std::make_move_iterator(left.end()));
data.push_back(mid);
data.insert(data.end(),
    std::make_move_iterator(right.begin()),
    std::make_move_iterator(right.end()));

Though I doubt this would make a difference for int.

like image 161
Jon Purdy Avatar answered Jan 06 '23 09:01

Jon Purdy