分阶段排名榜单

本文最后更新于:2025年5月25日 晚上

分阶段排名榜单

每一名都有对应的最低分数限制,只有超过此分数才能上榜。

满足当前阶段最低分数的人中,若超过了当前阶段的容纳人数,将按照分数倒序规则,把超出的最低分数的人数挤占到下一个排名阶段。若当前阶段的人数未满,空缺的将填充空值。

Java实现:

RankRule.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.test.utils;

// 等级规则类
class RankRule {
private int startRank; // 起始名次(包含)
private int endRank; // 结束名次(包含)
private int minScore; // 最低分数要求

// 构造方法 + getters
public RankRule(int startRank, int endRank, int minScore) {
this.startRank = startRank;
this.endRank = endRank;
this.minScore = minScore;
}

public boolean matches(int rank, int score) {
return rank >= startRank && rank <= endRank && score >= minScore;
}

// Getters
public int getStartRank() { return startRank; }
public int getEndRank() { return endRank; }
public int getMinScore() { return minScore; }
}

user.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.test.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 用户类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Double score;
}

test.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.hmall.test.utils;

import java.util.*;

/**
* 类名称
*
* @author peter
* @date 2025/4/6
* @description TODO
*/
public class Top {

private Top() {
throw new IllegalStateException("Utility class");
}

private static final Random random = new Random();

/**
* 生成榜单数据
* @param scores 原始数据
* @param rules 规则
* @param maxRank 榜单最大排名
*/
public static Map<Integer, User> generateRanking(List<User> scores, List<RankRule> rules, int maxRank) {
// 1. 按分数降序排序
scores.sort(Comparator.comparing(User::getScore).reversed());

// 2. 初始化榜单(TreeMap 自动按名次排序)
Map<Integer, User> ranking = new TreeMap<>();

// 3. 填充榜单
int currentRank = 1;
int index = 0; // 遍历 scores 的索引

for (RankRule rule : rules) {
// 处理当前规则的名次范围
while (currentRank <= rule.getEndRank() && index < scores.size()) {
Double score = scores.get(index).getScore();
if (score >= rule.getMinScore()) {
ranking.put(currentRank, scores.get(index));
currentRank++;
index++;
} else {
// 如果分数不达标,填充 null 并跳过
while (currentRank <= rule.getEndRank()) {
ranking.put(currentRank, null);
currentRank++;
}
break;
}
}
}

// 4. 处理剩余名次(如果规则未覆盖全部名次)
while (currentRank <= maxRank && index < scores.size()) {
ranking.put(currentRank, scores.get(index));
currentRank++;
index++;
}

// 5. 填充剩余空位(如果分数不足)
while (currentRank <= maxRank) {
ranking.put(currentRank, null);
currentRank++;
}

return ranking;
}

public static void main(String[] args) {
// 自定义排名规则(示例:第一名≥40000,第二三名≥15000,后续无限制)
List<RankRule> rules = Arrays.asList(
new RankRule(1, 1, 40000), // 第一名
new RankRule(2, 3, 15000), // 第二三名
new RankRule(4, 5, 10000), // 4-5名
new RankRule(6, 10, 7000), // 6-10名
new RankRule(11, 20, 5000), // 11-20名
new RankRule(21, 30, 3000), // 21-30名
new RankRule(31, 40, 2000), // 31-40名
new RankRule(41, 50, 1000) // 41-50名
);
List<User> scores = new ArrayList<>();
// 测试数据
scores.add(new User(1L, "peter", 40000.0));
scores.add(new User(2L, "Tom", 15000.0));
scores.add(new User(3L, "Alex", 10000.0));
scores.add(new User(4L, "Tomas", 7000.0));
scores.add(new User(5L, "Jerry", 5000.0));
scores.add(new User(6L, "Tim", 3000.0));
scores.add(new User(7L, "Vivo", 2000.0));
scores.add(new User(8L, "Apple", 1000.0));
scores.add(new User(9L, "Test", 6999.0));
// for (int i = 0; i < 45; i++){
// scores.add(new User(1L+i, "p"+i, (double) random.nextInt(40100)));
// }


// 生成榜单
Map<Integer, User> ranking = generateRanking(scores, rules,50);

System.out.println(" 排名 | 名称 | 分数 ");
// 打印结果
ranking.forEach((rank, user) ->
System.out.println(" " + rank + " | " + (user != null ? user.getName() : "NULL") + " | " +(user != null ? user.getScore() : "NULL"))
);
}
}

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
排名  |  名称  |  分数  
1 | NULL | NULL
2 | p16 | 38877.0
3 | p8 | 38837.0
4 | p20 | 38247.0
5 | p26 | 37243.0
6 | p35 | 36674.0
7 | p0 | 34689.0
8 | p29 | 34540.0
9 | p28 | 33794.0
10 | p4 | 33546.0
11 | p19 | 33192.0
12 | p18 | 33187.0
13 | p7 | 32324.0
14 | p10 | 30263.0
15 | p22 | 29967.0
16 | p3 | 29853.0
17 | p37 | 29327.0
18 | p41 | 27234.0
19 | p24 | 26986.0
20 | p39 | 25531.0
21 | p34 | 23169.0
22 | p17 | 22656.0
23 | p32 | 18923.0
24 | p40 | 17666.0
25 | p14 | 15360.0
26 | p21 | 14953.0
27 | p43 | 14848.0
28 | p44 | 14674.0
29 | p6 | 13527.0
30 | p9 | 13173.0
31 | p42 | 12349.0
32 | p31 | 9953.0
33 | p12 | 9020.0
34 | p30 | 8766.0
35 | p33 | 8537.0
36 | p15 | 8497.0
37 | p5 | 7528.0
38 | p27 | 7382.0
39 | p1 | 5509.0
40 | p23 | 4970.0
41 | p38 | 3469.0
42 | p13 | 3251.0
43 | p2 | 2303.0
44 | p25 | 1292.0
45 | NULL | NULL
46 | NULL | NULL
47 | NULL | NULL
48 | NULL | NULL
49 | NULL | NULL
50 | NULL | NULL

分阶段排名榜单
https://superlovelace.top/2025/04/06/分阶段榜单/
作者
棱境
发布于
2025年4月6日
更新于
2025年5月25日
许可协议