Tengo un arreglo ordenado de enteros, sobre el que desea realizar la búsqueda. Esta matriz puede tener valores repetidos. Si la búsqueda de un elemento que se repite, entonces debería devolver el índice de la primera instancia del elemento .
Si utilizo el Arrays.binarySearch()
, entonces no necesariamente dar a conocer el índice de la primera instancia del elemento buscado. Ejemplo se puede ver aquí :
int[] A = {10,20,21,24,24,24,24,24,30,40,45} ;
int idx = Arrays.binarySearch(A,24) ;
Cuando, idx
será 5
. Yo quiero que sea 3
. He resuelto este problema anteriormente al hacer una clase Pair
como:
class Pair implements Comparable<Pair>
{
int value, index ;
Pair(int v,int i)
{
this.value = v ;
this.index = i ;
}
@Override
public int compareTo(Pair p)
{
if(p.value<this.value)
return 1 ;
else if(p.value>this.value)
return -1 ;
else
{
if(p.index<this.index)
return 1 ;
else if(p.index>this.index)
return -1 ;
else return 0 ;
}
}
}
Que cuando se realizaron búsquedas con Collections.binarySearch(new Pair(24,Integer.MIN_VALUE))
(para una lista de Pair
s) devolvería una 3
. Después, el código sería:
int[] A = {10,20,21,24,24,24,24,24,30,40,45} ;
List<Pair> L = new ArrayList<Pair>() ;
for(int i=0;i<A.length;i++)
{
L.add(new Pair(A[i],i)) ;
}
int idx = Collections.binarySearch(L,new Pair(24,Integer.MIN_VALUE)) ;
if(idx<0) idx = -idx-1 ;
System.out.println(idx) ;
Pair
Funciona así: Tiene dos variables value
y index
, que son el valor del elemento de la matriz ordenada, y el índice del elemento de la matriz. El compareTo
método es reemplazado con el fin de permitir Collections.binarySearch()
realizar comparaciones. Las comparaciones pueden definirse así:
- Si la corriente
value
es mayor o menor, entonces la orden es decidir porvalue
. - Si
value
s son iguales, entonces el orden se decide utilizarindex
.
Mi pregunta es, se puede hacer esto de una manera desordenada menos? Todo lo que es más corto, sería muy apreciado!
Echar un vistazo a continuación pieza de código. Cambios en el código binario de búsqueda original hecho: l
y r
son la gama de izquierda y derecha, respectivamente
public static int binarySearch(int[] arr, int num, int l,int r) {
int mid = (l+r)/2;
if(arr[mid] == num && (mid>0&& arr[mid-1]!=num) || mid==0) {
return mid;
}
else if(arr[mid] > num || (mid > l && arr[mid] == num && arr[mid-1] == num)) {
return binarySearch(arr, num, l, mid);
}else {
return binarySearch(arr, num, mid, r);
}
}