简体   繁体   中英

Rank values of an Array

I have this input of array: int[] input = {1,3,2,2,33,1}; I need to make score for it like this output: {1,3,2,2,4,1} so the smallest number gets 1 and if there is smaller it gets 2 an so on. another example: for input {1,10,3,44,5,2,5} -outputs-> {1,5,3,6,4,2,4}

This is my try but it does not work as expected.

  public static int[] getRanksArray(int[] array) {
    int[] result = new int[array.length];

    for (int i = 0; i < array.length; i++) {
        int count = 0;
        for (int j = 0; j < array.length; j++) {
            if (array[j] != array[i]) {
                count++;
            }
        }
        result[i] = count + 1;
    }
    return result;
}

Edit : Updated to handle double rather than int input array.

First sort an array representing indices of the input array. Then walk through this array incrementing a rank counter whenever you encounter successive elements that are not equal ( ideone )

public static int[] rank(double[] nums)
{
  Integer[] idx = new Integer[nums.length];
  for(int i=0; i<idx.length; i++) idx[i] = i;

  Arrays.sort(idx, (a, b) -> (Double.compare(nums[a], nums[b])));

  // Or use this for descending rank
  // Arrays.sort(idx, (a, b) -> (Double.compare(nums[b], nums[a])));

  int[] rank = new int[nums.length];
  for(int i=0, j=1; i<idx.length; i++) 
  {
    rank[idx[i]] = j;
    if(i < idx.length - 1 && nums[idx[i]] != nums[idx[i+1]]) j++;
  }
  return rank;
}

Test:

System.out.println(Arrays.toString(rank(new double[] {1,3,2,2,33,1})));
System.out.println(Arrays.toString(rank(new double[] {1,10,3,44,5,2,5})));

Output:

[1, 3, 2, 2, 4, 1]
[1, 5, 3, 6, 4, 2, 4]

This can be solved using a sorted map storing lists/sets of indexes mapped by the values of the input array.

Then you can iterate over this map and fill the rank array with incrementing indexes.

Implementation:

    public static int[] rank(int[] arr) {
        TreeMap<Integer, List<Integer>> map = new TreeMap<>();
        for (int i = 0; i < arr.length; i++) {
            List<Integer> indexes = map.compute(arr[i], (k, v) -> v == null ? new ArrayList<>() : v);
            indexes.add(i);
            map.putIfAbsent(arr[i], indexes);
        }
        int[] rank = new int[arr.length];
        int id = 1;
        for (Map.Entry<Integer, List<Integer>> entry : map.entrySet()) {
            for(Integer i : entry.getValue()) {
                rank[i] = id;
            }
            id++;           
        }

        return rank;
    }

Test:

int[][] d = {
    {1,3,2,2,33,1},
    {1,10,3,44,5,2,5}
};

for (int[] input : d) {
    System.out.println(Arrays.toString(rank(input)));
}

output:

[1, 3, 2, 2, 4, 1]
[1, 5, 3, 6, 4, 2, 4]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM