Domanda

What is an elegant way to do the following in STL-style rather then for(;;):

Given p={1,2,3} and q={7,8,9}, i'd like to merge this to be pq={1,7,2,8,3,9}. one application is creating pq vector for integrating out of position (q) and momentum (p):

for(size_t i=0; i<p.size();++i) {
 pq.push_back(p[i]);
 pq.push_back(q[i]);
}

it's not elegant, it's not stl. it works but this question is about learning stl-style correctly rather then getting the job done so it's different from https://stackoverflow.com/questions/10746197/how-to-fit-elements-of-two-vectors-alternately-in-c (please comment before closing it so i can rephrase it)

the solution that i'm looking for should use some stl-algorithms and iterator manipulation. boost is good too.

È stato utile?

Soluzione

I don't know of an existing algorithm that's really suited to this task. The obvious alternative is to write roughly the code above, but as a generic algorithm:

template <class InIter1, class InIter2, class OutIter>
OutIter unsorted_merge(InIter1 b1, Inter1 e1, inIter2 b2, OutIter r) { 
    while (b1 != e1) {
        *r = *b1; ++r; ++b1;
        *r = *b2; ++r; ++b2;
    }
    return r;
};

Even though that code may not be particularly elegant or beautiful, the rest of the code can be:

unsorted_merge(p.begin(), p.end(), q.begin(), std::back_inserter(pq));

Altri suggerimenti

There's no STL algorithm that interleaves two data structures, if that's what you're asking. However, if you want an iterator-based solution, you could do something like this:

auto pIt = p.begin(), qIt = q.begin();
bool even = false;
while(pIt != p.end() && qIt != q.end()) {
  auto nextElement = (even = !even) ? pIt : qIt;
  pq.push_back(*nextElement);
  ++pIt;
  ++qIt;
}

This has the advantage of interleaving the first n elements of each vector, where n is the size of the smaller vector.

using lambda and boost::for_each (zip_iterator with std::for_each is similar):

vector<double> pq;
boost::for_each(
  p,q,
  [&pq](double p,double q) { 
    pq.push_back(p); pq.push_back(q);
  }
);

I didn't time it against Jerry's solution and I think Jerry's is more proper way but this is another option and it's easy to understand

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top