Jerry Coffin schrieb:
> In article <68adjjF2shlgaU1@[EMAIL PROTECTED]
>, quisquiliae@[EMAIL PROTECTED]
> says...
>> Hi,
>>
>> i have to vectors.
>> std::vector<double> a;
>> std::vector<double> b;
>> same type, size and have synchronous value pairs. The values in "a" are
>> decimal time values (linear increasing).
>>
>> Now i want to copy in a 3rd vector "c" all elements from a start value
>> to a end value. My first idea was something like:
>>
>> std::vector<double> c; // target
>> for (std::vector<double>::iterator it=a.begin(); it != a.end(); it++) {
>> if (*it > startvalue && *it < endvalue) {
>> c.push_back(?);
>> }
>> }
>>
>> do i need a 2nd iterator for vector b !? but how?
>> or ist there a easier was to get the values to vector c?
>
> As I understand it, you want to take all the values that are in a or b
> that fall within some specified range, and copy them into c.
>
> If that's the case, one method would be something like this:
>
> template <class T>
> class out_of_range {
> T lower_;
> T upper_;
> public:
> out_of_range(T const &lower, T const &upper) :
> lower_(lower), upper_(upper)
> {}
>
> bool operator()(T const &value) {
> return std::less(value, lower) || std::less(upper, value);
> }
> };
>
> std::remove_copy_if(a.begin(),
> a.end(),
> std::back_inserter(c),
> out_of_range(startvalue, endvalue));
>
> std::remove_copy_if(b.begin(),
> b.end(),
> std::back_inserter(c)
> out_of_range(startvalue, endvalue));
>
> If there are likely to be a lot of values outside the specified range,
> this isn't very efficient. In such a case, it's faster to use a binary
> search to find your two end-points, and then copy everything in-between:
>
> std::vector<double>::iterator start, stop;
>
> start = std::lower_bound(a.begin(), a.end(), startvalue);
> stop = std::upper_bound(a.begin(), a.end(), endvalue);
>
> std::copy(start, stop, std::back_inserter(c));
>
> start = std::lower_bound(b.begin(), b.end(), startvalue);
> stop = std::upper_bound(b.begin(), b.end(), endvalue);
>
> std::copy(start, stop, std::back_inserter(c));
>
> Note that this produces all the elements from a before any of the
> elements from b. If you want then in order instead, you have a couple of
> choices. One is to just sort c after doing the above. Another is to
> merge the ranges instead of just copying the items one after the other:
>
> starta = std::lower_bound(a.begin(), a.end(), startvalue);
> stopa = std::upper_bound(a.begin(), a.end(), endvalue);
>
> startb = std::lower_bound(a.begin(), a.end(), startvalue);
> stopb = std::lower_bound(a.begin(), a.end(), endvalue);
>
> std::merge(starta, stopa, startb, stopb, std::back_inserter(c));
>
Thanks. For the moment it works using an index.
So i have some time to analyse and test your tips and replace the code.


|