-1

I have a “two dimensional” data stored in a double array in a row major way. My data has 5 columns, time, x, y, z, and field.

  1. T1, x1, y1, z1, F1
  2. T2, x2, y2, z2, F2
  3. T3, x3, y3, z3, F3 …

This data is stored in a double 1D array in row major way. Like

double dataArray[] = { T1, x1, y1,z1,F1, T2,x2,y2,z2,F2, T3,x3,y3,z3,F3, ... };

Now I want to find the first row of the data for which time is equal to or greater than a given value T0. How can I use std::lower_bound to do this?

I guess that I need a ForwardIterator which returns every 5th element in that array but don't how to do that. Any help is appreciated.

  • 1
    Looks like XY problem. Store data in proper format (struct with double fields) and not only your problem would be gone, but your code would become more readable and less error prone – Slava Feb 22 '17 at 16:53
  • this might help: http://stackoverflow.com/questions/5685983/skipping-iterator – NathanOliver Feb 22 '17 at 16:58
  • @Slava, I can't change the way data is stored. – user3469604 Feb 22 '17 at 17:36
  • It's common (for example when interfacing with fortran) to encounter data in row major format. It'd be pretty inefficient to change representation just to iterate over it. The great thing about C++ is you can define types that work in expected ways on any data format. – Art Yerkes Feb 22 '17 at 17:47
  • @ArtYerkes, exactly my situation, my dataArray comes from a FORTRAN subroutine and I cannot change the underline data structure. Same data is accessed in FORTRAN as well as C++ routines. – user3469604 Feb 22 '17 at 17:54
  • "You can write FORTRAN in any language" – Slava Feb 22 '17 at 18:24

1 Answers1

0

You can write an iterator to do what you want pretty easily. I'm not aware of a drop-in that does just this.

#include <algorithm>
#include <iostream>

template <typename T> struct SkipIt : public std::iterator<std::forward_iterator_tag, T> {
    SkipIt(T *t, unsigned skip) : elt(t), skip(skip) {}
    bool operator == (const SkipIt<T> &other) const { return elt == other.elt; }
    bool operator != (const SkipIt<T> &other) const { return elt != other.elt; }
     T *operator -> () const { return elt; }
    T &operator * () const { return *elt; }
    SkipIt &operator ++ () { elt += skip; return *this; }
    SkipIt operator ++ (int) { auto ret = *this; ++*this; return ret; }
    SkipIt operator + (int amt) const { auto ret = SkipIt(elt + amt * skip, skip); return ret; }

private:
    unsigned skip;
    T *elt;
};

int main() {
    double test[] =
        { 0.1, 0.2, 0.3
        , 1.1, 1.2, 1.3
        , 2.1, 2.2, 2.3
        , 3.1, 3.2, 3.3
        };
    auto begin = SkipIt<double>(test, 3);
    auto end = begin + 4;
    auto res = std::lower_bound(begin, end, 2.0);
    if (res == end) {
        std::cout << "Lower bound not found\n";
    } else {
        std::cout << "Lower bound of 2.0: " << *res << "\n";
    }
}
Art Yerkes
  • 1,274
  • 9
  • 9