Busque igual, más grande o más pequeño en una array ordenada en Java

Dada la array de enteros ordenados, la clave de búsqueda y las preferencias de búsqueda encuentran la posición de la array. Las preferencias de búsqueda pueden ser:
1) IGUAL: busca solo la clave igual o -1 si no se encuentra. Es una búsqueda binaria normal.
2) EQUAL_OR_SMALLER: busca solo la clave igual o la más pequeña más cercana. -1 si no se encuentra.
3) EQUAL_OR_BIGGER: busque solo la clave igual o la más grande más cercana. -1 si no se encuentra.

Ejemplos:

Input : { 0, 2, 4, 6 }, key -1, EQUAL 
Output : -1

Input : { 0, 2, 4, 6 }, key -1, EQUAL_OR_BIGGER
Output : 0

Input : { 0, 2, 4, 6 }, key 7, EQUAL_OR_BIGGER
Output : -1

Input : { 0, 2, 4, 6 }, key 7, EQUAL_OR_SMALLER
Output : 3

En el algoritmo de búsqueda binaria regular, la evaluación y la división se realizan en la medida en que el tamaño del subarreglo sea mayor que 0.
En nuestro caso, si queremos mantener una función única, debemos realizar la evaluación final en un subarreglo de tamaño = 2. Solo en tamaño de subarreglo == 2 es posible verificar las condiciones EQUAL_OR_SMALLER y EQUAL_OR_BIGGER.

En el siguiente código, SC significa Criterios de búsqueda .

public class BinarySearchEqualOrClose {
  
    private static void printResult(int key, int pos,
                                    SC sC)
    {
        System.out.println("" + key + ", " + sC + ":" + pos);
    }
  
    enum SC {
        EQUAL,
        EQUAL_OR_BIGGER,
        EQUAL_OR_SMALLER
    };
  
    public static int searchEqualOrClose(int key, int[] arr, SC sC)
    {
        if (arr == null || arr.length == 0) {
            return -1;
        }
  
        if (arr.length == 1) { // just eliminate case of length==1
  
            // since algorithm needs min array size==2
            // to start final evaluations
            if (arr[0] == key) {
                return 0;
            }
            if (arr[0] < key && sC == SC.EQUAL_OR_SMALLER) {
                return 0;
            }
            if (arr[0] > key && sC == SC.EQUAL_OR_BIGGER) {
                return 0;
            }
            return -1;
        }
        return searchEqualOrClose(arr, key, 0, arr.length - 1, sC);
    }
  
    private static int searchEqualOrClose(int[] arr, int key,
                                          int start, int end, SC sC)
    {
        int midPos = (start + end) / 2;
        int midVal = arr[midPos];
        if (midVal == key) {
            return midPos; // equal is top priority
        }
  
        if (start >= end - 1) {
            if (arr[end] == key) {
                return end;
            }
            if (sC == SC.EQUAL_OR_SMALLER) {
  
                // find biggest of smaller element
                if (arr[start] > key && start != 0) {
  
                    // even before if "start" is not a first
                    return start - 1;
                }
                if (arr[end] < key) {
                    return end;
                }
                if (arr[start] < key) {
                    return start;
                }
                return -1;
            }
            if (sC == SC.EQUAL_OR_BIGGER) {
  
                // find smallest of bigger element
                if (arr[end] < key && end != arr.length - 1) {
  
                    // even after if "end" is not a last
                    return end + 1;
                }
                if (arr[start] > key) {
                    return start;
                }
                if (arr[end] > key) {
                    return end;
                }
                return -1;
            }
            return -1;
        }
        if (midVal > key) {
            return searchEqualOrClose(arr, key, start, midPos - 1, sC);
        }
        return searchEqualOrClose(arr, key, midPos + 1, end, sC);
    }
  
    public static void main(String[] args)
    {
        int[] arr = new int[] { 0, 2, 4, 6 };
  
        // test full range of xs and SearchCriteria
        for (int x = -1; x <= 7; x++) {
            int pos = searchEqualOrClose(x, arr, SC.EQUAL);
            printResult(x, pos, SC.EQUAL);
            pos = searchEqualOrClose(x, arr, SC.EQUAL_OR_SMALLER);
            printResult(x, pos, SC.EQUAL_OR_SMALLER);
            pos = searchEqualOrClose(x, arr, SC.EQUAL_OR_BIGGER);
            printResult(x, pos, SC.EQUAL_OR_BIGGER);
        }
    }
}
Producción:

-1, EQUAL:-1
-1, EQUAL_OR_SMALLER:-1
-1, EQUAL_OR_BIGGER:0
0, EQUAL:0
0, EQUAL_OR_SMALLER:0
0, EQUAL_OR_BIGGER:0
1, EQUAL:-1
1, EQUAL_OR_SMALLER:0
1, EQUAL_OR_BIGGER:1
2, EQUAL:1
2, EQUAL_OR_SMALLER:1
2, EQUAL_OR_BIGGER:1
3, EQUAL:-1
3, EQUAL_OR_SMALLER:1
3, EQUAL_OR_BIGGER:2
4, EQUAL:2
4, EQUAL_OR_SMALLER:2
4, EQUAL_OR_BIGGER:2
5, EQUAL:-1
5, EQUAL_OR_SMALLER:2
5, EQUAL_OR_BIGGER:3
6, EQUAL:3
6, EQUAL_OR_SMALLER:3
6, EQUAL_OR_BIGGER:3
7, EQUAL:-1
7, EQUAL_OR_SMALLER:3
7, EQUAL_OR_BIGGER:-1

Complejidad de tiempo: O (log n)

Publicación traducida automáticamente

Artículo escrito por LeonidPurgalin y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *