Home > Back-end >  java comparator for searching 2D array
java comparator for searching 2D array

Time:04-11

I have a 2D integer array [n][3] and a target value. I sort the array using

Arrays.sort(arr, (a,b)->Integer.compare(a[1],b[1]));

How can I use Arrays.binarySearch and a custom comparator to search arr along index 1 for a target value? Something that could replace the following:

   int binSearch(int[][] arr, int target) {
      int low=0, high=arr.length-1;
      while( low < high ) {
         int mid=(low high)/2;
         if( arr[mid][1] == target ) {
            return i;
         }    
         else if( arr[mid][1] < target {
            low=mid 1;
         }
         else {
            high=mid-1;
         }
      }
      return -(low 1);
   }

EDIT: Arrays.sort works how I need it to - my initial array for example {{1,3,5},{7,1,6},{4,2,1}} sorts on the middle value to {{7,1,6},{4,2,1},{1,3,5}}

I thought I could write a similar expression for Arrays.binarySearch where each element (1x3) of the array is compared to a target integer. Something like:

int idx = Arrays.binarySearch(arr, target, (a,b)->Integer.compare(a[1],b));

I can't really use the same comparator as in the sort because they are different types - the search array is an array of 1x3 sized elements and my target is a single integer. I need to do a binary search.

CodePudding user response:

I think I better understand your case now.

Maybe once you've ordered the matrix as you've done, you can extract an array populated with the middle elements and then apply the binary search on it. Although, I don't really know your use case and how many elements you're handling, it might be too expensive...

int vetMiddleCol[] = IntStream.range(0, mat.length)
                .boxed()
                .mapToInt(i -> mat[i][1])
                .toArray();

int index = binarySearch(vetMiddleCol, target);

At that point, the index returned from the binary search will correspond to the element mat[index][1].

CodePudding user response:

Static method Arrays.binarySearch() has the following declaration:

public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)

Where T is the type of the elements in the array. In this case, it happens to be int[].

The important distinction between your method binSearch() and Arrays.binarySearch() is that your method expects an int argument target, meanwhile you need to pass int[] into binarySearch().

Since the required comparator needs only the second element (i.e. at index 1) of the array, the other elements of the key can have any value. Therefore, an array of two elements, like that

new int[]{0, target} // the first value, is arbitrary

will be a sufficient in order to utilize the built-in binarySearch().

int index = Arrays.binarySearch(source, new int[]{0, i}, comparator);

To define a comparator, you might make use of static methods comparing() and comparingInt() of the Comparator interface introduced with Java 8.

With that, the code bowls down to a couple of lines, and might be written like that:

public static void main(String[] args) {
    int[][] source = {{1, 3, 5}, {7, 1, 6}, {4, 2, 1}};
    
    Comparator<int[]> bySecondElement = Comparator.comparingInt(arr -> arr[1]);
    
    Arrays.sort(source, bySecondElement);
    
    for (int i = 0; i < 4; i  ) { // searching for arrays having a value of i as second element
        int index = Arrays.binarySearch(source, new int[]{0, i}, bySecondElement);
        System.out.printf("target: %d\tindex: %d\n", i, index);
    }
}

Output

target: 0   index: -1   // no such element
target: 1   index: 0    // {7, 1, 6}
target: 2   index: 1    // {4, 2, 1}
target: 3   index: 2    // {1, 3, 5}
  • Related