-2

我有一个由 4 个整数组成的数组,它们代表 4 个玩家的得分。我想得到另一个数组,根据他们的分数给我球员的排名。

例如:
给定分数 {10,20,15,40}
我希望排名为 {4,2,3,1}

最低分数为 4 级,最高分数为 1 级。

最大的问题是当有多个玩家得分相同时。例如 {10,10,20,40} 那么我想得到 {34,34,2,1} (34 因为第三和第四名是两个玩家共享的)

另一个例子是 {40,40,10,20},它应该给出排名 {12,12,4,3}(12 表示共享第一和第二名)

目前我有两个双重数组来得出这个结果,但我认为它可以更好,但我不知道如何。我现在最大的问题是当我们有 3 个相同的分数时:{40,40,40,10} 比我应该得到的结果 {123,123,123,4}

我希望你能理解我的问题,当然可以帮助我找到解决方案。

谢谢

4

1 回答 1

3

首先,创建我们将使用分数排序的索引:

final double[] scores = // acquire scores
Integer[] indices = new Integer[scores.length];
Arrays.sort(indexes, new Comparator<Integer>() {
    @Override public int compare(Integer i, Integer j) {
        return -Double.compare(scores[i], scores[j]);
    }
});

请注意,我们使用 a-降序排序。

现在,我们使用 排序了我们的分数indices,并考虑了重复分数的可能性。接下来,我们将收集每个分数的所有指标。我们将通过构建一个从分数到该分数的索引列表的映射来做到这一点。

Map<Double, SortedSet<Integer>> map =
    new HashMap<Double, SortedSet<Integer>>();
for(int i = 0; i < scores.length; i++) {
    if(!map.containsKey(scores[i])) {
        map.puts(scores[i], new TreeSet<Integer>());
    }
    map.get(scores[i]).add(indexes[i] + 1);
}

我们使用SortedSet以便索引按顺序出现,我们添加1是因为您的排名从一开始而不是零。

现在,如果您遍历分数,您可以从HashMap.

for(int i = 0; i < scores.length; i++) {
    SortedSet<Integer> set = map.get(scores[i]);
    System.out.print(scores[i] + ": ");
    Iterator<Integer> iterator = set.iterator();
    System.out.print(iterator.next());
    while(iterator.hasNext()) {
        System.out.print("," + iterator.next());
    }
    System.out.println();
}

当我在您的示例上运行它时[40, 40, 10, 20],我看到了输出:

40: 1,2
40: 1,2
10: 3
20: 4

和上[40, 40, 40, 10]

40: 1,2,3
40: 1,2,3
40: 1,2,3
10: 4

和上[10, 10, 20, 40]

10: 3,4
10: 3,4
20: 2
40: 1

从这里开始,应该很容易修改以获得您想要的排名。

让我们来看看这在心理上是如何运作的。我们将使用示例[40, 40, 10, 20]。首先,我们建立索引:

indexes = [0, 1, 2, 3]

然后我们使用分数对索引进行排序;

indexes = [0, 1, 3, 2]

然后我们收集每个分数的所有排名(请记住,我们在上一步的索引中添加了一个):

map = { 40 : [1, 2], 10 : [4], 20 : [3] }

然后,对于 中的每个分数scores,我们可以查找 中的所有等级map并将它们转储到控制台。

于 2013-06-29T20:02:26.543 回答