Вид Массива Java: Быстрый способ получить отсортированный список индексов массива

добавьте что-то подобное в ваш код

  if( IPAddress.Parse(a).AddressFamily == AddressFamily.InterNetwork )
  // IPv4 address
38
задан Stefan Zobel 25 November 2018 в 14:54
поделиться

7 ответов

Я бы адаптировал алгоритм быстрой сортировки для выполнения операции обмена одновременно с несколькими массивами: массивом индексов и массивом значений. Например (на основе этого quicksort ):

public static void quicksort(float[] main, int[] index) {
    quicksort(main, index, 0, index.length - 1);
}

// quicksort a[left] to a[right]
public static void quicksort(float[] a, int[] index, int left, int right) {
    if (right <= left) return;
    int i = partition(a, index, left, right);
    quicksort(a, index, left, i-1);
    quicksort(a, index, i+1, right);
}

// partition a[left] to a[right], assumes left < right
private static int partition(float[] a, int[] index, 
int left, int right) {
    int i = left - 1;
    int j = right;
    while (true) {
        while (less(a[++i], a[right]))      // find item on left to swap
            ;                               // a[right] acts as sentinel
        while (less(a[right], a[--j]))      // find item on right to swap
            if (j == left) break;           // don't go out-of-bounds
        if (i >= j) break;                  // check if pointers cross
        exch(a, index, i, j);               // swap two elements into place
    }
    exch(a, index, i, right);               // swap with partition element
    return i;
}

// is x < y ?
private static boolean less(float x, float y) {
    return (x < y);
}

// exchange a[i] and a[j]
private static void exch(float[] a, int[] index, int i, int j) {
    float swap = a[i];
    a[i] = a[j];
    a[j] = swap;
    int b = index[i];
    index[i] = index[j];
    index[j] = b;
}
16
ответ дан 27 November 2019 в 03:17
поделиться

Я думаю, самый простой способ сделать это - индексировать массив по мере его создания. Вам понадобятся пары ключ-значение. Если индекс представляет собой отдельную структуру, то я не понимаю, как вы могли бы сделать это без других объектов (хотя заинтересованы в этом)

-2
ответ дан 27 November 2019 в 03:17
поделиться

Преобразуйте входные данные в парный класс, как показано ниже, и затем отсортируйте его с помощью массивов. Сортировать(). Arrays.sort () гарантирует, что исходный порядок сохраняется для равных значений, как это делает Matlab.

0
ответ дан 27 November 2019 в 03:17
поделиться

С Функциональная Java :

import static fj.data.Array.array;
import static fj.pre.Ord.*;
import fj.P2;

array(d).toStream().zipIndex().sort(p2Ord(doubleOrd, intOrd))
  .map(P2.<Double, Integer>__2()).toArray();
7
ответ дан 27 November 2019 в 03:17
поделиться

Создайте TreeMap значений индексов.

    float[] array = new float[]{};
    Map<Float, Integer> map = new TreeMap<Float, Integer>();
    for (int i = 0; i < array.length; ++i) {
        map.put(array[i], i);
    }
    Collection<Integer> indices = map.values();

индексы будут отсортированы по числам с плавающей запятой, на которые они указывают, исходный массив останется нетронутым. Преобразование Collection в int [] остается в качестве упражнения, если это действительно необходимо.

EDIT: Как отмечено в комментариях, этот подход не работает, если в массиве с плавающей запятой есть повторяющиеся значения. Эту проблему можно решить, превратив Map в Map > , хотя это усложнит внутреннюю часть цикла for и генерацию окончательный сборник немного.

23
ответ дан 27 November 2019 в 03:17
поделиться

Более общий случай ответа Джерико , который допускает повторяющиеся значения, будет следующим:

// Assuming you've got: float[] array; defined already

TreeMap<Float, List<Integer>> map = new TreeMap<Float, List<Integer>>();
for(int i = 0; i < array.length; i++) {
    List<Integer> ind = map.get(array[i]);
    if(ind == null){
        ind = new ArrayList<Integer>();
        map.put(array[i], ind);
    }
    ind.add(i);
}

// Now flatten the list
List<Integer> indices = new ArrayList<Integer>();
for(List<Integer> arr : map.values()) {
    indices.addAll(arr);
}
2
ответ дан 27 November 2019 в 03:17
поделиться

Простое решение для создания массива индексатора: отсортируйте индексатор, сравнивая значения данных:

final Integer[] idx = { 0, 1, 2, 3 };
final float[] data = { 1.7f, -0.3f,  2.1f,  0.5f };

Arrays.sort(idx, new Comparator<Integer>() {
    @Override public int compare(final Integer o1, final Integer o2) {
        return Float.compare(data[o1], data[o2]);
    }
});
30
ответ дан 27 November 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: