-1

I have a set of ordered, non-overlapping intervals that do not share boundaries, e.g.:

long[][] intervals = new long[][]{
    new long[]{ 2, 3 },
    new long[]{ 5, 10 },
    new long[]{ 25, 1200 },
    ...
}

Currently I use a binary search algorithm to find out if value x is contained by one of the ranges. This is a lot CPU work and involves looping over ranges.

My idea is now to form a polynomial function where y >= 0 exactly when one interval contains the value x and y < 0 if not. This function can be calculated up front and be reused: I pass any x and can use the resulting y to see if it is fine or not.

Advantages I expect over the binary search:

  • If I have a limited set of ranges I can prepare the function to be reused over multiple x where when using the binary function I would need to run it again for every `x´ again.
  • Only one if (for deciding if smaller than 0 or not)

How can I build such polynomial function given a set of intervals?

Sebastian Barth
  • 4,079
  • 7
  • 40
  • 59
  • 1
    Evaluating the polynomial would be more costly than your current method (a lot of additions and multiplications would be needed). – Olivier Jun 05 '22 at 13:56
  • Isn't it just `y=(x-2)*(x-3)*(x-5)*(x-10)*(x-25)*(x-1200)`? – Progman Jun 05 '22 at 14:03
  • @Olivier I doubt that. I create the combined polynomial once and reuse it. The reuse is just plain addition and multiplication, everything prepared. No jumps and at max one loop (over components). The binary search instead necessarily has a lot of if-else, minimum one per binary step. The polynominal requieres only one at the end: y > 0. – Sebastian Barth Jun 14 '22 at 06:58

1 Answers1

-1

Are you looking for something like this?

public static void main(String[] args) {
    long[][] intervals = new long[][]{
            new long[]{2, 3},
            new long[]{5, 10},
            new long[]{25, 1200}
    };
    long numberToFind = 26;
    long[] interval = findInterval(intervals, numberToFind);
    if (interval.length > 0) {
        System.out.println(numberToFind + " is in range: " + interval[0] + " to " + interval[interval.length - 1]);
    }else {
        System.out.println(numberToFind + " is not in range");
    }

}

private static long[] findInterval(long[][] intervals, long numberToFind) {
    for (long[] interval : intervals) {
        if (numberToFind >= interval[0] && numberToFind <= interval[interval.length - 1]) {
            return interval;
        }
    }
    return new long[0];
}
Eskandar Abedini
  • 2,090
  • 2
  • 13