custom sorting a java array

前端 未结 4 929
长情又很酷
长情又很酷 2021-01-06 03:41

I have an [] that has some numbers (distances from some point).
I want to create an array of indexes into the first array where the indexes are sorted by the distance.

相关标签:
4条回答
  • 2021-01-06 04:09

    Works well if you want the indicies as a primative int array then you will have to create your own binary sorter which shouldn't be to difficult.

    Edit: I adapted java's mergesorter to work with int's. This should save you a little time in writing your own.

    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;
        }
    
    0 讨论(0)
  • 2021-01-06 04:18

    I did try it now and it works! :)

    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
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 04:18

    You should customize your own Comparator and use java API.

    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

    0 讨论(0)
  • 2021-01-06 04:32

    You're on the right track, but

    • You're better off with an Integer array than an int array if you're using a generic Comparator<Integer>.
    • You have to use Arrays.sort instead Collections.sort for sorting an array.
    • You have to make the distances variable final if it's referenced in an anonymous inner class.

      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]);
          }
      });
      
    0 讨论(0)
提交回复
热议问题