i have algorithm requires applying set union many times growing sets of integers. efficiency represent sets sorted vectors, union can obtained merging them.
a classical way merge 2 sorted vectors this:
void inmerge(vector<int> &a, const vector<int> &b) { a.reserve(a.size() + b.size()); std::copy(b.begin(), b.end(), std::back_inserter(a)); std::inplace_merge(a.begin(), a.end() - b.size(), a.end()); }
unfortunately, std::inplace_merge
appears slower std::sort
in case, because of allocation overhead. fastest way use std::merge
directly output 1 of vectors. in order not write value before reading it, have proceed ends, this:
void inmerge(vector<int> &a, const vector<int> &b) { a.resize(a.size() + b.size()); orig_a_rbegin = a.rbegin() + b.size(); std::merge(orig_a_rbegin, a.rend(), b.rbegin(), b.rend(), a.rend(), [](int x, int y) { return x > y; }); }
it sure implementation of merge
never write more elements has read, safe thing do. unfortunately, c++ standard (even c++17 draft) forbids this:
the resulting range shall not overlap either of original ranges.
is okay ignore restriction if know i'm doing?
no, ignoring mandate of standard (or other documentation of library you're using) never ok. may know you doing, sure know library doing - or might doing in next version?
for example, merge algorithm detect @ least 2 of ranges reverse ranges, unwrap them (and unwrap or reverse third), , merge in other direction. no observable difference long preconditions kept, possibly tiny bit faster since overhead of reverse iterators gone. screw code.
Comments
Post a Comment