Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's equivalent to bisect in python

Is there an equivalent in Java for Python's bisect module? With Python's bisect you can do array bisection with directions. For instance bisect.bisect_left does:

Locate the proper insertion point for item in list to maintain sorted order. The parameters lo and hi may be used to specify a subset of the list which should be considered; by default the entire list is used.

I know I can do this manually with a binary search too, but I was wondering if there is already a library or collection doing this.

like image 427
systemsfault Avatar asked May 31 '10 17:05

systemsfault


People also ask

Is bisect built in Python?

NOTE: Bisect Module comes preinstalled with the Python distributions.

What does bisect return Python?

The bisect_left() method is provided by the bisect module, which returns the left-most index to insert the given element, while maintaining the sorted order.

What is bisect Insort?

The bisect module in Python assists in preserving a list in a sorted order, as it bypasses the sort operation after each insertion. Insort is one of the functions of the bisect module.


2 Answers

You have two options:

  • java.util.Arrays.binarySearch on arrays
    • (with various overloads for different array types)
  • java.util.Collections.binarySearch on List
    • (with Comparable and Comparator overloads).
    • Combine with List.subList(int fromIndex, int toIndex) to search portion of a list
like image 161
polygenelubricants Avatar answered Sep 20 '22 15:09

polygenelubricants


To this date (Java 8), this is still missing, so you must still make your own. Here's mine:

public static int bisect_right(int[] A, int x) {
    return bisect_right(A, x, 0, A.length);
}

public static int bisect_right(int[] A, int x, int lo, int hi) {
    int N = A.length;
    if (N == 0) {
        return 0;
    }
    if (x < A[lo]) {
        return lo;
    }
    if (x > A[hi - 1]) {
        return hi;
    }
    for (;;) {
        if (lo + 1 == hi) {
            return lo + 1;
        }
        int mi = (hi + lo) / 2;
        if (x < A[mi]) {
            hi = mi;
        } else {
            lo = mi;
        }
    }
}

public static int bisect_left(int[] A, int x) {
    return bisect_left(A, x, 0, A.length);
}

public static int bisect_left(int[] A, int x, int lo, int hi) {
    int N = A.length;
    if (N == 0) {
        return 0;
    }
    if (x < A[lo]) {
        return lo;
    }
    if (x > A[hi - 1]) {
        return hi;
    }
    for (;;) {
        if (lo + 1 == hi) {
            return x == A[lo] ? lo : (lo + 1);
        }
        int mi = (hi + lo) / 2;
        if (x <= A[mi]) {
            hi = mi;
        } else {
            lo = mi;
        }
    }
}

Tested with (X being the class where I store static methods that I intend to reuse):

@Test
public void bisect_right() {
    System.out.println("bisect_rienter code hereght");
    int[] A = new int[]{0, 1, 2, 2, 2, 2, 3, 3, 5, 6};
    assertEquals(0, X.bisect_right(A, -1));
    assertEquals(1, X.bisect_right(A, 0));
    assertEquals(6, X.bisect_right(A, 2));
    assertEquals(8, X.bisect_right(A, 3));
    assertEquals(8, X.bisect_right(A, 4));
    assertEquals(9, X.bisect_right(A, 5));
    assertEquals(10, X.bisect_right(A, 6));
    assertEquals(10, X.bisect_right(A, 7));
}

@Test
public void bisect_left() {
    System.out.println("bisect_left");
    int[] A = new int[]{0, 1, 2, 2, 2, 2, 3, 3, 5, 6};
    assertEquals(0, X.bisect_left(A, -1));
    assertEquals(0, X.bisect_left(A, 0));
    assertEquals(2, X.bisect_left(A, 2));
    assertEquals(6, X.bisect_left(A, 3));
    assertEquals(8, X.bisect_left(A, 4));
    assertEquals(8, X.bisect_left(A, 5));
    assertEquals(9, X.bisect_left(A, 6));
    assertEquals(10, X.bisect_left(A, 7));
}
like image 24
Profiterole Avatar answered Sep 18 '22 15:09

Profiterole