如果比赛地点相等"the same"如何分配给排序列表元素?



我有一个运动员名单(姓名,分数,地点(,已经设置了姓名和分数。我需要根据分数获得他们在比赛中的名次。

目前我将它们放在一个 TreeSet ,所以它们已经按升序排序。如果所有分数都不同,我可以这样做:

    int place=1;        
    for (Athlete athlete:allAthletes){
        athlete.setRelativePlace(place++);
    }

问题是,如果两个运动员的分数相同,他们必须有"1-2"或"8-9-10"作为分配的位置。 例如,获胜者都获得了 8000 分,他们都应该在他们的位置字段中有一个字符串"1-2"。下一个人 - 如果她的分数是唯一的 - 将得到正常的"3",依此类推。有没有办法在几行简单的行中做到这一点,而不必做两个循环并在运动员课中添加额外的字段?

这不是一个完整的答案,但一次通过生成您想要的所有运动员的排名并不难。 与其使用8-9-10作为排名标签,我建议只对所有三名运动员使用8。 也就是说,有三名运动员并列第 8 名。

int rank = 0;
int score = -1;
for (Athlete a : allAthletes) {
    int currScore = a.getScore();
    if (currScore != score) {
        ++rank;
        score = currScore;
    }
    a.setRelativePlace(rank);
}

这种排名系统就是数据库术语中所说的"密集排名"。 使用这个方案,如果有两名运动员并列第一名,三名并列第三名,我们将有以下排名:

score | dense rank
100   | 1
100   | 1
95    | 2
80    | 3
80    | 3
80    | 3

编辑:假设您坚持自己的要求,请考虑以下脚本。 与其依赖你的类,除非我猜到你的代码是什么样子,否则我无法测试,我只是按升序在排序的分数列表中打印排名。

List<Integer> scores = new ArrayList<>();
scores.add(80);
scores.add(80);
scores.add(80);
scores.add(90);
scores.add(100);
scores.add(100);
Collections.sort(scores);
int pos = 0;
int score = -1;
int prevScore = -1;
int a = 0;
for (int currScore : scores) {
    System.out.println("DEBUG: current score is: " + currScore);
    if (score == -1) {
        score = currScore;
        prevScore = currScore;
        ++a;
        continue;
    }
    if (score != currScore || a == scores.size() - 1) {
        String rank = "";
        prevScore = score;
        // this covers the case of the last score, or group of scores
        if (a == scores.size() - 1) ++a;
        for (int i=0; i < a - pos; ++i) {
            if (i > 0) rank += "-";
            rank += (pos + i + 1);
        }
        for (int i=pos; i < a; ++i) {
            System.out.println("Score " + prevScore + " has rank " + rank);
        }
        score = currScore;
        pos = a;
    }
    ++a;
}
Score 80 has rank 1-2-3
Score 80 has rank 1-2-3
Score 80 has rank 1-2-3
Score 90 has rank 4
Score 100 has rank 5-6
Score 100 has rank 5-6

点击下面的链接获取上述代码片段的运行演示。

演示

目前我将它们保存在 TreeSet 中,因此它们已经按升序排序。如果您在存储在树集中时比较运动员分数,则 TreeSet 不会保持两个运动员具有相同的分数。

假设相对地点是 int 类型。最好将运动员存储在列表中并使用比较器对其进行排序。得分相同的运动员将按广告顺序列出。

 public class Athlete {
     private String name;
     private int score;
     private int relativePlce;
 }

排序会像..

athletes.sort((o1, o2) -> new Integer(o1.getScore()).compareTo(o2.getScore()));
    int place = 1;
    for (Athlete athlete : athletes) {
        athlete.setPlcae(place++);
        System.out.println( athlete.getName()+":"+athlete.getScore() + ":" + athlete.getPlcae());

由于现在只有一个setRelativePlace(int),可以存储起始位置:

int priorScore = -1;
int priorPlace = -1;
int place = 0;        
for (Athlete athlete: allAthletes) {
    int score = athlete.getScore();
    ++place;
    if (score != priorScore) {
        priorScore = score;
        priorPlace = place;
    }
    athlete.setRelativePlace(priorPlace);
}

拥有一系列地方的数据结构,可以修补最后找到的地方:

static class Place {
    int start;
    int end; // inclusive
    @Override
    String toString() {
        if (start == end) {
            return Integer.toString(start);
        }
        return IntStream.rangeClosed(start, end)
            .map(Integer::toString)
            .collect(Collectors.joining("-"));
    }
}
int priorScore = -1;
Place priorPlace = null;
int place = 0;        
for (Athlete athlete: allAthletes) {
    int score = athlete.getScore();
    ++place;
    if (score != priorScore) {
        priorScore = score;
        priorPlace = new Place();
        priorPlace.start = place;
    }
    priorPlace.end = place;
    athlete.setRelativePlace(priorPlace);
}

当 allAthlete 是一个排序列表并且您有两个 int 字段开始和结束时:

int priorScore = -1;
int priorPlace = -1;
for (int place = 0; ; ++place) {
    if (place == allAthletes.size() || allAthletes.get(place)) {
        for (int p = priorPlace; p < place; ++p) {
            allAthletes.setTillPlace(place - 1);
        }
    }
    if (place == allAthlets.size()) {
        break;
    }
    int score = athlete.getScore();
    if (score != lastScore) {
        priorScore = score;
        priorPlace = place;
    }
    athlete.setRelativePlace(priorPlace);
}

最新更新