with a given ordered list of integers, we can rank like 1, 2, 2, 4, 5, 5, 5, 8, …

static List<Integer> ranks(final List<Integer> values) {
    final List<Integer> ranks = new ArrayList<Integer>(values.size());
    int previous = Integer.MAX_VALUE;
    int rank = 0;
    int tie = 0;
    for (int value : values) {
        if (value < previous) {
            tie = 0;
        } else if (value == previous) {
            tie++;
        } else {
            throw new IllegalArgumentException("not ordered descendant");
        }
        ranks.add(++rank - tie);
        previous = value;
    }
    return ranks;
}
public static void main(final String[] args) {
    final List<Integer> values = new ArrayList<Integer>();
    final Random random = new Random();
    int value = random.nextInt(100);
    for (int i = 0; i < 20; i++) {
        if (random.nextBoolean()) {
            value = random.nextInt(100);
        }
        values.add(value);
    }
    Collections.sort(values);
    Collections.reverse(values);
    final List<Integer> ranks = ranks(values);
    for (int i = 0; i < values.size(); i++) {
        System.out.printf("%1$d\t%2$d\n", values.get(i), ranks.get(i));
    }
}
96      1
93      2
93      2
88      4
88      4
70      6
68      7
68      7
54      9
45      10
45      10
27      12
27      12
27      12
26      15
26      15
19      17
15      18
9       19
9       19
static <T extends Comparable<? super T>> List<Integer> ranks(final List<T> values) {

    if (values == null) {
        throw new NullPointerException("null values");
    }

    if (values.isEmpty()) {
        return Collections.<Integer>emptyList();
    }

    final List<Integer> ranks = new ArrayList<Integer>(values.size());

    final Iterator<T> iterator = values.iterator();
    T previous = iterator.next();
    int rank = 1;
    ranks.add(rank);
    int tie = 0;
    int compare = 0;
    for (T next = null; iterator.hasNext();) {
        if ((next = iterator.next()) == null) {
            throw new NullPointerException("null element");
        }
        compare = previous.compareTo(next);
        if (compare < 0) {
            throw new IllegalArgumentException("not ordered descendant");
        } else if (compare == 0) {
            tie++;
        } else {
            tie = 0;
        }
        ranks.add(++rank - tie);
        previous = next;
    }

    return ranks;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s