6

いくつかの数字(ある時点からの距離)を持つ[]があります。
インデックスが距離でソートされている最初の配列にインデックスの配列を作成したいと思います。

例えば

次にdouble[] dist=new double[5] {3.2, 1.4, 7.3, 2.2, 9.1};
、次のような配列を取得したいとします。

int[] sortedIndexes=new int[5] {1, 3, 0, 2, 4};

したがって、2番目に近い距離が必要な場合は、dist[sortedIndexes[1]]を確認できます。
元の配列を並べ替えるのではなく、距離に基づいたインデックスの配列だけを並べ替えます。

更新1:私が試していたコードは次のようになります:

Collections.sort(sortedIDXs, new Comparator<Integer>() {
    public int compare(int idx1, int idx2) {
        return Double.compare(distances[idx1], distances[idx2]);
    }
});

しかし、私はそれでいくつかのエラーを受け取ります。最も「問題のある」ものは次のとおりです。「別のメソッドで定義された内部クラス内の非最終変数距離を参照することはできません

ありがとう

4

4 に答える 4

19

あなたは正しい方向に進んでいますが、

  • ジェネリックを使用している場合は、Integer配列よりも配列の方が適しています。intComparator<Integer>
  • Arrays.sort代わりに、配列の並べ替えに使用する必要がありますCollections.sort
  • 匿名の内部クラスで参照されている場合は、distances変数をfinalにする必要があります。

    final double[] distances=new double[]{3.2, 1.4, 7.3, 2.2, 9.1};
    Integer[] sortedIDXs  = new Integer[]{0,1,2,3,4};
    Arrays.sort(sortedIDXs, new Comparator<Integer>() {
        public int compare(Integer idx1, Integer idx2) {
            return Double.compare(distances[idx1], distances[idx2]);
        }
    });
    
于 2012-05-06T15:43:46.760 に答える
3

インデックスを基本的なint配列として使用する場合は、独自のバイナリソーターを作成する必要がありますが、これは難しいことではありません。

編集:私はJavaのmergesorterをintで動作するように適合させました。これにより、自分で作成する時間を少し節約できます。

public static void main(String[] args) {
        double[] dist = new double[] {3.2, 1.4, 7.3, 2.2, 9.1};
        int[] indices = createIndicies(dist);

        System.out.println(Arrays.toString(dist) + " " +  Arrays.toString(indices));
    }

    public static int[] createIndicies(double[] array) {
        int[] intArray = new int[array.length];
        for (int j = 0; j < array.length; j++) {
            intArray[j] = j;
        }

        int[] indicies = intArray.clone();
        mergeSort(intArray, indicies, 0, intArray.length, 0, new IndiciesSorter(array));

        return indicies;
    }

    public static class IndiciesSorter implements Comparator<Integer> {

        double[] array;

        public IndiciesSorter(double[] array) {
            this.array = array;
        }

        @Override
        public int compare(Integer o1, Integer o2) {
            return Double.compare(array[o1], array[o2]);
        }
    }

    private static void mergeSort(int[] src, int[] dest, int low,
            int high, int off, Comparator c) {
        int length = high - low;

        // Insertion sort on smallest arrays
        if (length < 7) {
            for (int i = low; i < high; i++)
                for (int j = i; j > low && c.compare(dest[j - 1], dest[j]) > 0; j--)
                    swap(dest, j, j - 1);
            return;
        }

        // Recursively sort halves of dest into src
        int destLow = low;
        int destHigh = high;
        low += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off, c);
        mergeSort(dest, src, mid, high, -off, c);

        // If list is already sorted, just copy from src to dest. This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (c.compare(src[mid - 1], src[mid]) <= 0) {
            System.arraycopy(src, low, dest, destLow, length);
            return;
        }

        // Merge sorted halves (now in src) into dest
        for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
    }

    private static void swap(int[] x, int a, int b) {
        int t = x[a];
        x[a] = x[b];
        x[b] = t;
    }
于 2012-05-06T15:43:04.473 に答える
-1

独自のコンパレータをカスタマイズし、JavaAPIを使用する必要があります。

http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html#sort(java.lang.Object []、%20int、%20int)

http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

于 2012-05-06T15:24:30.247 に答える
-1

私は今それを試しました、そしてそれはうまくいきます!:)

double[] dist= {3.2, 1.4, 7.3, 2.2, 9.1}; // your array
int[] sortedIndexes= new int[dist.length]; // your array

double[] temp = dist.clone(); // clone the array
Arrays.sort(temp); // Use native array sort function

for(int i = 0; i<temp.length; i++) { // iterate through sorted array
    for(int j = 0; j<dist.length; j++) { // iterate through original array
        if (dist[j] == temp[i]) { // if sorted value == unsorted value
            sortedIndexes[i] = j; // save position of match into your sortedIndex array
        }
    }
}
于 2012-05-06T15:29:15.557 に答える