У меня есть отсортированный массив целых чисел, по которому я хочу выполнить поиск.Этот массив может иметь повторяющиеся значения. Если я ищу элемент, который повторяется, то он должен вернуть индекс первого экземпляра элемента .
Если я использую Arrays.binarySearch()
, то это не обязательновыдают индекс первого экземпляра искомого элемента.Пример можно увидеть здесь :
int[] A = {10,20,21,24,24,24,24,24,30,40,45} ;
int idx = Arrays.binarySearch(A,24) ;
Где, idx
будет 5
.Я хочу, чтобы это было 3
.Я решил эту проблему ранее, создав класс Pair
, например:
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 ;
}
}
}
, который при поиске с помощью Collections.binarySearch(new Pair(24,Integer.MIN_VALUE))
(для списка Pair
s) вернул бы 3
.Тогда код будет выглядеть так:
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
работает следующим образом: он имеет две переменные value
и index
, которые являются значением элемента отсортированного массива, и индексомэлемент в массиве.Метод compareTo
переопределен, чтобы позволить Collections.binarySearch()
выполнять сравнения.Сравнения могут быть определены следующим образом:
- Если текущий
value
больше или меньше, то порядок определяется value
. - Если
value
sто же самое, тогда порядок определяется с помощью index
.
Мой вопрос: можно ли сделать это менее грязным способом?Все, что короче, будет с благодарностью!