Як знайти індекс елемента в масиві int?


81

Як я можу знайти індекс певного значення в масиві Java типу int?

Я намагався використовувати Arrays.binarySearchсвій невідсортований масив, він лише іноді дає правильну відповідь.


12
Двійковий пошук ніколи не працюватиме на невідсортованому масиві.
Chris Eberle

Тоді ви можете мені щось запропонувати, як я повинен це зробити. Тому що якщо я сортую масив, я втрачаю відстеження індексів, і мені потрібно знати, з якого індексу отримано значення ??
Jeomark

EDIT: я забув додати, мені також потрібно знайти індекс масиву для подвійних значень.
Jeomark

1
Якщо ви не хочете сортувати масив, просто використовуйте простий цикл for, щоб знайти значення.
Джеймі Кертіс,

2
Як правило, добре читати документацію щодо функцій :) From binarySearch: "Шукає вказаний масив ... за вказаним значенням за допомогою двійкового алгоритму пошуку. Масив потрібно відсортувати (як за методом sort (long [])) до для здійснення цього виклику. Якщо він не відсортований, результати не визначені. ... "

Відповіді:


133
Integer[] array = {1,2,3,4,5,6};

Arrays.asList(array).indexOf(4);

Зауважте, що це рішення безпечне для потоку, оскільки воно створює новий об’єкт типу List.

Крім того, ви не хочете викликати це в циклі або щось подібне, оскільки ви кожен раз створюєте новий об'єкт


Дякую, але чи спрацює це для типу double? Вибачте, я забув згадати у питанні, але мені також потрібно попрацювати над подвійними значеннями. Хоча це чудово працює з ints.
Jeomark

Так би, не потрібно нічого міняти (але тип масиву, очевидно)
Пабло Фернандес,

54
Насправді код не працює. Перевірте, чому indexOf не вдається знайти об’єкт?
телун

14
Вам потрібно перетворити масив на Integer [] замість int []. примітивні масиви не автококсуються.
Леон Хелмслі,

1
Це насправді безпечно? Коли я натискаю джерело, List.asList () створює ArrayList, який приймає масив int безпосередньо як контейнер даних (не копіюючи)
Langusten Gustel

26

Іншим варіантом, якщо ви використовуєте колекції Guava, є Ints.indexOf

// Perfect storm:
final int needle = 42;
final int[] haystack = [1, 2, 3, 42];

// Spoiler alert: index == 3
final int index = Ints.indexOf(haystack, needle);

Це чудовий вибір, коли повторне використання простору, часу та коду має високу ціну. Це також дуже стисло.


20

Погляньте на API і там сказано, що спочатку потрібно відсортувати масив

Так:

Arrays.sort(array);
Arrays.binarySearch(array, value);

Якщо ви не хочете сортувати масив:

public int find(double[] array, double value) {
    for(int i=0; i<array.length; i++) 
         if(array[i] == value)
             return i;
}

7
+1 Однак слід зазначити, що Arrays.sort мутує вхідні дані, і вихідний масив буде змінено.

спасибі, 2-й метод якось спрацював у мене після додавання логіки для повторюваних значень з різними індексами.
Jeomark

14

Скопіюйте цей метод у свій клас

 public int getArrayIndex(int[] arr,int value) {

        int k=0;
        for(int i=0;i<arr.length;i++){

            if(arr[i]==value){
                k=i;
                break;
            }
        }
    return k;
}

Викличте цей метод із передачею двох пераметрів Array та value та збережіть його повернене значення у цілочисельній змінній.

int indexNum = getArrayIndex(array,value);

Дякую


6
ArrayUtils.indexOf(array, value);
Ints.indexOf(array, value);
Arrays.asList(array).indexOf(value);

3
Хоча цей код може вирішити питання, включаючи пояснення того, як і чому це вирішує проблему, насправді допомогло б поліпшити якість вашої публікації, і, можливо, призведе до більшої кількості голосів. Пам’ятайте, що ви відповідаєте на запитання читачам у майбутньому, а не лише тому, хто задає зараз. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення та вказати, які обмеження та припущення застосовуються.
подвійний звуковий сигнал

4

Ви можете використовувати сучасну Java для вирішення цієї проблеми. Будь ласка, використовуйте код нижче:

static int findIndexOf(int V, int[] arr) {
        return IntStream.range(1, arr.length).filter(i->arr[i]==V).findFirst().getAsInt();
    }

Чудово! Дякую, що поділились. Це допомагає дізнатися про нові (оптимізовані) вбудовані рішення в контексті мовних можливостей.
Гільєрмо Гарсія


3

Вам потрібно відсортувати значення перед використанням двійкового пошуку. В іншому випадку ручний спосіб полягає в тому, щоб спробувати всі ints на вашій вкладці.

public int getIndexOf( int toSearch, int[] tab )
{
  for( int i=0; i< tab.length ; i ++ )
    if( tab[ i ] == toSearch)
     return i;

  return -1;
}//met

Альтернативним методом може бути зіставлення всього індексу для кожного значення на карті.

tab[ index ] = value;
if( map.get( value) == null || map.get( value) > index )
    map.put( value, index );

а потім map.get (value), щоб отримати індекс.

З повагою, Стефане

@pst, дякую за ваші коментарі. Чи можете ви опублікувати інший альтернативний метод?


Це один із шляхів, так. Однак це не єдиний спосіб. Використання логічної змінної foundтут марне (і не використовується) і його слід видалити. +1 за показ "методу ручного циклу", хоча (стилістичні та форматування проблеми в сторону).

2

Просто:

public int getArrayIndex(int[] arr,int value) {
    for(int i=0;i<arr.length;i++)
        if(arr[i]==value) return i;
    return -1;
}

2
    Integer[] arr = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
    List<Integer> arrlst = Arrays.asList(arr);
    System.out.println(arrlst.lastIndexOf(1));

Зверніть увагу, що масив має бути Integer [], а не int []. Принаймні, indexOf () працює лише з Integer
djdance

1

Якщо хтось все ще шукає відповідь -

  1. Ви можете використовувати ArrayUtils.indexOf () із [Бібліотеки Apache Commons] [1].

  2. Якщо ви використовуєте Java 8, ви також можете використовувати Strean API:

    public static int indexOf(int[] array, int valueToFind) {
        if (array == null) {
            return -1;
        }
        return IntStream.range(0, array.length)
                .filter(i -> valueToFind == array[i])
                .findFirst()
                .orElse(-1);
    }
    

    [1]: https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/ArrayUtils.html#indexOf(int[],%20int)


1

Найпростіший спосіб - повторити. Наприклад, ми хочемо знайти мінімальне значення масиву та його індекс:

public static Pair<Integer, Integer> getMinimumAndIndex(int[] array) {
        int min = array[0];
        int index = 0;
        for (int i = 1; i < array.length; i++) {
            if (array[i] < min) {
                min = array[i];
                index = i;
            }

            return new Pair<min, index>;

Таким чином ви перевіряєте всі значення масиву, і якщо деякі з них є мінімальними, ви також знаєте індекс мінімумів. Він може працювати так само з пошуком якогось значення:

public static int indexOfNumber(int[] array) {
        int index = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == 77) {        // here you pass some value for example 77
                index = i;
            }
        }
        return index;
    }

0

Ви можете або пройтись по масиву, поки не знайдете потрібний індекс, або Listзамість нього використати . Зверніть увагу, що ви можете перетворити масив у список за допомогою asList().


0
/**
     * Method to get the index of the given item from the list
     * @param stringArray
     * @param name
     * @return index of the item if item exists else return -1
     */
    public static int getIndexOfItemInArray(String[] stringArray, String name) {
        if (stringArray != null && stringArray.length > 0) {
            ArrayList<String> list = new ArrayList<String>(Arrays.asList(stringArray));
            int index = list.indexOf(name);
            list.clear();
            return index;
        }
        return -1;
    }

І clearта new ArrayListє непотрібними операціями. Виділення нової ArrayListкопії цілого масиву, що безглуздо, оскільки Arrays.asListвже повертає метод, Listякий має indexOfметод. Очищати копію списку непотрібно, GC все одно забере її.
TWiStErRob

0

Ви можете зробити це так:

 public class Test {

public static int Tab[]  = {33,44,55,66,7,88,44,11,23,45,32,12,95};
public static int search = 23;

public static void main(String[] args) {
    long stop = 0;
    long time = 0;
    long start = 0;
    start = System.nanoTime();
    int index = getIndexOf(search,Tab);
    stop = System.nanoTime();
    time = stop - start;
    System.out.println("equal to took in nano seconds ="+time);
    System.out.println("Index  of searched value is: "+index);
    System.out.println("De value of Tab with searched index is: "+Tab[index]);
    System.out.println("==========================================================");
    start = System.nanoTime();
    int Bindex = bitSearch(search,Tab);
    stop = System.nanoTime();
    time = stop - start;
    System.out.println("Binary search took nano seconds ="+time);
    System.out.println("Index  of searched value is: "+Bindex);
    System.out.println("De value of Tab with searched index is: "+Tab[Bindex]);
}



public static int getIndexOf( int toSearch, int[] tab ){
     int i = 0;
     while(!(tab[i] == toSearch) )
     {  i++; }
       return i; // or return tab[i];
   }
public static int bitSearch(int toSearch, int[] tab){
    int i = 0;
    for(;(toSearch^tab[i])!=0;i++){
    }
    return i;

}

}

Додано XOR :)


tab.equals(toSearch)- це порівняння масиву з int. Можливо, tab[i] == toSearchзамість цього.
Mike Samuel

Це працює, дякуючи Майку ... Google за двійковий пошук, кілька приємних статей та цікавий метод
Андре

@Andre якщо ви намагаєтеся довести свою точку дати їм рівні ( той же порядок, то ж управління потоком): while (tab[i] != toSearch) i++;VS while ((tab[i] ^ toSearch) != 0) i++;.
TWiStErRob

1
У будь-якому випадку такий спосіб хронометражу не працює, для мене bitSearchзавжди швидший, ніж getIndexOf; хоча якщо я просто поміняю місцями дзвінки на два методи, це getIndexOfстає швидше, ніж bitSearch. Це наочно демонструє, що другий з якихось причин внутрішніх органів JVM завжди швидший. Вам слід повторити експеримент багато разів (можливо, мільйони), усереднюючи значення, відкидаючи екстремальні значення і роблячи розминку, дуже схожу на тест.
TWiStErRob

0

В основному методі, який використовує for циклів: -третій цикл for у моєму прикладі є відповіддю на це питання. -в моєму прикладі я створив масив з 20 випадкових цілих чисел, призначив змінній найменше число і зупинив цикл, коли розташування масиву досягло найменшого значення під час підрахунку кількості циклів.

import java.util.Random;
public class scratch {
    public static void main(String[] args){
        Random rnd = new Random();
        int randomIntegers[] = new int[20];
        double smallest = randomIntegers[0];
        int location = 0;

        for(int i = 0; i < randomIntegers.length; i++){             // fills array with random integers
            randomIntegers[i] = rnd.nextInt(99) + 1;
            System.out.println(" --" + i + "-- " + randomIntegers[i]);
        }

        for (int i = 0; i < randomIntegers.length; i++){            // get the location of smallest number in the array 
            if(randomIntegers[i] < smallest){
                smallest = randomIntegers[i];                 
            }
        }

        for (int i = 0; i < randomIntegers.length; i++){                
            if(randomIntegers[i] == smallest){                      //break the loop when array location value == <smallest>
                break;
            }
            location ++;
        }
        System.out.println("location: " + location + "\nsmallest: " + smallest);
    }
}

Код видає всі числа та їх розташування, а також розташування найменшого числа, за яким слідує найменше число.


0
static int[] getIndex(int[] data, int number) {
    int[] positions = new int[data.length];
    if (data.length > 0) {
        int counter = 0;
        for(int i =0; i < data.length; i++) {
            if(data[i] == number){
                positions[counter] = i;
                counter++;
            }
        }
    }
    return positions;
}

0

Двійковий пошук: двійковий пошук також може бути використаний для пошуку індексу елемента масиву в масиві. Але двійковий пошук можна використовувати, лише якщо сортується масив. Java надає нам вбудовану функцію, яку можна знайти в бібліотеці масивів Java, яка поверне індекс, якщо елемент присутній, інакше він повертає -1. Складність буде O (log n). Нижче представлена ​​реалізація двійкового пошуку.

public static int findIndex(int arr[], int t) { 
   int index = Arrays.binarySearch(arr, t); 
   return (index < 0) ? -1 : index; 
} 

-2
Integer[] array = {1, 2, 3, 4, 5, 6};

for (int i = 0; i < array.length; i++) {
    if (array[i] == 4) {
        system.out.println(i);
        break;
    }
}

3
Дубльована відповідь.
betontalpfa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.