0

If have this code (taken from https://stackoverflow.com/a/4859279/1178781):

import java.util.Comparator;

public class ArrayIndexComparator<T extends Comparable<? super T>> implements
        Comparator<Integer> {
    private final T[] array;

    public ArrayIndexComparator(T[] array) {
        this.array = array;
    }

    public Integer[] createIndexArray() {
        Integer[] indexes = new Integer[array.length];
        for (int i = 0; i < array.length; i++) {
            indexes[i] = i; // Autoboxing
        }
        return indexes;
    }

    @Override
    public int compare(Integer index1, Integer index2) {
        // Autounbox from Integer to int to use as array indexes
        return array[index1].compareTo(array[index2]);
    }
}

When I run the program this happens:

import java.util.Arrays;
import java.util.Comparator;

public class Launcher {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String[] countries = { "A", "H", "E", "C", "D", "F", "G", "B" };
        ArrayIndexComparator<String> comparator = new ArrayIndexComparator<String>(
                countries);
        Integer[] indexes = comparator.createIndexArray();
        Arrays.sort(indexes, comparator);
        System.out.print("Array:    ");
        System.out.println(Arrays.toString(countries));
        System.out.print("Rankings: ");
        System.out.println(Arrays.toString(indexes));
        System.out.println("");

        final Float[] scores2 = { 2.3f, 0.7f, 1.4f, 1.2f };
        ArrayIndexComparator<Float> comparator2 = new ArrayIndexComparator<Float>(
                scores2);
        indexes = comparator2.createIndexArray();
        Arrays.sort(indexes, comparator2);
        System.out.print("Array:    ");
        System.out.println(Arrays.toString(scores2));
        System.out.print("Rankings: ");
        System.out.println(Arrays.toString(indexes));
        System.out.println("");

        final Integer[] scores3 = { 1, 2, 0, 3 };
        ArrayIndexComparator<Integer> comparator3 = new ArrayIndexComparator<Integer>(
                scores3);
        indexes = comparator3.createIndexArray();
        Arrays.sort(indexes, comparator3);
        System.out.print("Array:    ");
        System.out.println(Arrays.toString(scores3));
        System.out.print("Rankings: ");
        System.out.println(Arrays.toString(indexes));
        System.out.println("");

        final Integer[] scores4 = { 1, 0, 2, 3 };
        ArrayIndexComparator<Integer> comparator4 = new ArrayIndexComparator<Integer>(
                scores4);
        indexes = comparator4.createIndexArray();
        Arrays.sort(indexes, comparator4);
        System.out.print("Array:    ");
        System.out.println(Arrays.toString(scores4));
        System.out.print("Rankings: ");
        System.out.println(Arrays.toString(indexes));
        System.out.println("");

    }

}

The output is as follows:

Array:    [A, H, E, C, D, F, G, B]
Rankings: [0, 7, 3, 4, 2, 5, 6, 1]

Array:    [2.3, 0.7, 1.4, 1.2]
Rankings: [1, 3, 2, 0]

Array:    [1, 2, 0, 3]
Rankings: [2, 0, 1, 3]

Array:    [1, 0, 2, 3]
Rankings: [1, 0, 2, 3]

I thought that this should correctly give the Rankings of the objects in the array, but certain configurations do not do that. Am I missing something? Or is this not actually sorting to give Rankings, but something else?

For example:

Array:    [A, H, E, C, D, F, G, B]
Rankings: [0, 7, 3, 4, 2, 5, 6, 1]
Should be:[0, 7, 4, 2, 3, 5, 6, 1]

Array:    [2.3, 0.7, 1.4, 1.2]
Rankings: [1, 3, 2, 0]
Should be:[3, 0, 2, 1]

Array:    [1, 2, 0, 3]
Rankings: [2, 0, 1, 3]
Should be:[1, 2, 0, 3]    

Array:    [1, 0, 2, 3]
Rankings: [1, 0, 2, 3]
Should be:[1, 0, 2, 3]
Community
  • 1
  • 1
justderb
  • 2,835
  • 1
  • 25
  • 38

1 Answers1

0

Based on the fact that you don't need to consider duplicates you can change everything around to look like this:

public static void main(String[] args) {
    String[] countries = { "A", "H", "E", "C", "D", "F", "G", "B" };
    ArrayComparator<String> comparator = new ArrayComparator<String>(
            countries);
    Integer[] indexes = comparator.createIndexArray();
    System.out.print("Array:     ");
    System.out.println(Arrays.toString(countries));
    System.out.print("Rankings: ");
    System.out.println(Arrays.toString(indexes));
    System.out.println("");

    final Float[] scores2 = { 2.3f, 0.7f, 1.4f, 1.2f };
    ArrayComparator<Float> comparator2 = new ArrayComparator<Float>(
            scores2);
    indexes = comparator2.createIndexArray();
    System.out.print("Array:     ");
    System.out.println(Arrays.toString(scores2));
    System.out.print("Rankings: ");
    System.out.println(Arrays.toString(indexes));
    System.out.println("");

    final Integer[] scores3 = { 1, 2, 0, 3 };
    ArrayComparator<Integer> comparator3 = new ArrayComparator<Integer>(
            scores3);
    indexes = comparator3.createIndexArray();
    System.out.print("Array:     ");
    System.out.println(Arrays.toString(scores3));
    System.out.print("Rankings: ");
    System.out.println(Arrays.toString(indexes));
    System.out.println("");

    final Integer[] scores4 = { 1, 0, 2, 3 };
    ArrayComparator<Integer> comparator4 = new ArrayComparator<Integer>(
            scores4);
    indexes = comparator4.createIndexArray();
    System.out.print("Array:     ");
    System.out.println(Arrays.toString(scores4));
    System.out.print("Rankings: ");
    System.out.println(Arrays.toString(indexes));
    System.out.println("");

}

public class ArrayComparator<T extends Comparable<? super T>>{
    private final T[] array;
    private final SortedMap<T, Integer> sortedArray;

    public ArrayComparator(T[] array){
        this.array = array;
        sortedArray = new TreeMap<T, Integer>();
        for(int i = 0 ; i < array.length ; i ++){
            sortedArray.put(array[i], Integer.valueOf(i));
        }
    }

    public Integer[] createIndexArray(){
        Integer[] indexArray = new Integer[sortedArray.size()];
        int i = 0;
        for(T key : sortedArray.keySet()){
            indexArray[sortedArray.get(key)] = i;
            i++;
        }
        return indexArray;
    }
}

Then run it and your output looks like this:

Array:     [A, H, E, C, D, F, G, B]
Rankings:  [0, 7, 4, 2, 3, 5, 6, 1]

Array:     [2.3, 0.7, 1.4, 1.2]
Rankings:  [3, 0, 2, 1]

Array:     [1, 2, 0, 3]
Rankings:  [1, 2, 0, 3]

Array:     [1, 0, 2, 3]
Rankings:  [1, 0, 2, 3]

Which is what I believe you are looking for.

nattyddubbs
  • 2,085
  • 15
  • 24
  • The output you gave just sorts the `score`s, it does not give me the rankings for each `score`. It already 'sorts' the `score`s but does so on the `int` array. – justderb Feb 28 '13 at 20:14
  • So you are expecting the sorted `indexes` array to map directly to the "ranking" of the item at the same index in the `scores4` array? If so I don't know that's what it's intended for. The original post doesn't reference "ranking" of any kind. – nattyddubbs Feb 28 '13 at 20:35
  • I've updated my question at the bottom. Hopefully this should help see what I want to do... – justderb Feb 28 '13 at 20:47