|
Prev: Wanna do a WriteLongwordBits contest ? (Skybuck's SimInt64 C/C++ version)
Next: Callback function and templates
From: Gerhard Wolf on 6 May 2008 02:53 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?
From: Jim Langston on 6 May 2008 03:37 Gerhard Wolf wrote: > 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? It is hard to understand what, exactly, you want vector c to end up containing. For example, say vector a is: 1.0, 1.5, 2.0, 2.5 and vector b is: 12.0, 12.25, 12.5, 12.75 What do you want vector c to contain? In this case it would probably be better to use an index. for ( std::size_t i = 0; i < a.size() && i < b.size(); ++i ) { // Here you can reference a[i] and b[i] or a.at(i) b.at(i) } -- Jim Langston tazmaster(a)rocketmail.com
From: Francis Glassborow on 6 May 2008 03:40 Gerhard Wolf wrote: > 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). You mean they are sorted? If they aren't create a couple of working copies and sort them. Now look up std::merge. Note that all sequence algorithms work correctly as long as you can provide start and one past the end iterators for the sequence. In this case you need the iterator for the first element of the (sorted) a and b that is greater than the startvalue and the the iterators for the first element in each that is greater than the endvalue. Also note that you will need to know how many elements there will eventually be in the merged result. > > 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?
From: Gerhard Wolf on 6 May 2008 03:41 Jim Langston schrieb: > Gerhard Wolf wrote: >> 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? > > It is hard to understand what, exactly, you want vector c to end up > containing. > > For example, say vector a is: > 1.0, 1.5, 2.0, 2.5 > and vector b is: > 12.0, 12.25, 12.5, 12.75 > > What do you want vector c to contain? > > In this case it would probably be better to use an index. > > for ( std::size_t i = 0; i < a.size() && i < b.size(); ++i ) > { > // Here you can reference a[i] and b[i] or a.at(i) b.at(i) > } > > ok this seems to be the easiest way. thanks
From: Jerry Coffin on 7 May 2008 01:45
In article <68adjjF2shlgaU1(a)mid.individual.net>, quisquiliae(a)gmx.de 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)); -- Later, Jerry. The universe is a figment of its own imagination. |