鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者 、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen)
统计射击比赛成绩(Java、JavaScript、Python 和 C++)
算法实现
问题描述:
在一个射击比赛中,每个参赛者都有多个射击成绩。根据每个参赛者的最高3个成绩,对他们进行排名。如果某个参赛者没有3个或以上的成绩,则该参赛者无效,不参与排名。
解决方案:
-
数据结构:
- 使用数据结构存储每个参赛者的成绩。字典或哈希表是合适的选择。
- 字典的键是参赛者ID,值是他们的成绩列表。
-
处理成绩:
- 遍历成绩列表,跟踪每个参赛者的成绩。
- 对于每个成绩,将其添加到相应参赛者的成绩列表中。
- 如果参赛者的成绩列表已经包含3个成绩,则丢弃新成绩。
-
排名参赛者:
- 创建新的数据结构存储排名。字典或哈希表再次适合。
- 遍历参赛者数据结构:
- 对于每个参赛者,计算其最高3个成绩的总和。
- 使用总和作为键,参赛者ID作为值,添加到排名数据结构中。
- 按键(总和)降序排序排名数据结构。
- 排序后的排名数据结构表示最终的参赛者排名。
代码实现
Java:
import java.util.*;
public class ShootingCompetitionRanker {
public static Map<String, Integer> rankParticipants(Map<String, List<Integer>> scores) {
Map<String, Integer> rankings = new HashMap<>();
for (Map.Entry<String, List<Integer>> entry : scores.entrySet()) {
String participantId = entry.getKey();
List<Integer> participantScores = entry.getValue();
// Sort scores in descending order
Collections.sort(participantScores, Collections.reverseOrder());
// Calculate sum of top 3 scores (if available)
int top3Sum = 0;
for (int i = 0; i < Math.min(participantScores.size(), 3); i++) {
top3Sum += participantScores.get(i);
}
if (top3Sum > 0) {
rankings.put(participantId, top3Sum);
}
}
// Sort rankings by top 3 scores in descending order
Map.Entry<String, Integer>[] rankingsArray = rankings.entrySet().toArray(new Map.Entry[0]);
Arrays.sort(rankingsArray, (a, b) -> b.getValue().compareTo(a.getValue()));
Map<String, Integer> sortedRankings = new HashMap<>();
for (Map.Entry<String, Integer> entry : rankingsArray) {
sortedRankings.put(entry.getKey(), entry.getValue());
}
return sortedRankings;
}
public static void main(String[] args) {
Map<String, List<Integer>> scores = new HashMap<>();
scores.put("A", Arrays.asList(100, 80, 90, 75));
scores.put("B", Arrays.asList(95, 85, 70));
scores.put("C", Arrays.asList(60, 70, 80, 95, 100));
scores.put("D", Arrays.asList(50, 60));
Map<String, Integer> rankings = rankParticipants(scores);
System.out.println("Rankings:");
for (Map.Entry<String, Integer> entry : rankings.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
JavaScript:
function rankParticipants(scores) {
const rankings = {};
for (const [participantId, participantScores] of Object.entries(scores)) {
// Sort scores in descending order
participantScores.sort((a, b) => b - a);
// Calculate sum of top 3 scores (if available)
let top3Sum = 0;
for (let i = 0; i < Math.min(participantScores.length, 3); i++) {
top3Sum += participantScores[i];
}
if (top3Sum > 0) {
rankings[participantId] = top3Sum;
}
}
// Sort rankings by top 3 scores in descending order
const rankingsArray = Object.entries(rankings);
rankingsArray.sort((a, b) => b[1] - a[1]);
const sortedRankings = {};
for (const [participantId, top3Sum] of rankingsArray) {
sortedRankings[participantId] = top3Sum;
}
return sortedRankings;
}
const scores = {
"A": [100, 80, 90, 75],
"B": [95, 85, 70],
"C": [60, 70, 80, 95, 100],
"D": [50, 60],
};
const rankings = rankParticipants(scores);
console.log("Rankings:");
for (const [participantId, top3Sum] of Object.entries(rankings)) {
console.log(`${participantId}: ${top3Sum}`);
}
Python:
def rank_participants(scores):
rankings = {}
for participant_id, participant_scores in scores.items():
# Sort scores in descending order
participant_scores.sort(reverse=True)
# Calculate sum of top 3 scores (if available)
top3_sum = 0
for i in range(min(len(participant_scores), 3)):
top3_sum += participant_scores[i]
if top3_sum > 0:
rankings[participant_id] = top3_sum
# Sort rankings by top 3 scores in descending order
sorted_rankings = {k: v for k, v in sorted(rankings.items(), key=lambda item: item[1], reverse=True)}
return sorted_rankings
scores = {
"A": [100, 80, 90, 75],
"B": [95, 85, 70],
"C": [60, 70, 80, 95, 100],
"D": [50, 60],
}
rankings = rank_participants(scores)
print("Rankings:")
for participant_id, top3_sum in rankings.items():
print(f"{participant_id}: {top3_sum}")
C++:
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
map<string, int> rankParticipants(map<string, vector<int>> scores) {
map<string, int> rankings;
for (const auto& entry : scores) {
string participantId = entry.first;
vector<int>& participantScores = entry.second;
// Sort scores in descending order
sort(participantScores.begin(), participantScores.end(), greater<int>());
// Calculate sum of top 3 scores (if available)
int top3Sum = 0;
for (int i = 0; i < min(static_cast<int>(participantScores.size()), 3); i++) {
top3Sum += participantScores[i];
}
if (top3Sum > 0) {
rankings[participantId] = top3Sum;
}
}
// Sort rankings by top 3 scores in descending order
vector<pair<string, int>> rankingsArray(rankings.begin(), rankings.end());
sort(rankingsArray.begin(), rankingsArray.end(), [](const pair<string, int>& a, const pair<string, int>& b) {
return b.second > a.second;
});
map<string, int> sortedRankings;
for (const auto& pair : rankingsArray) {
sortedRankings[pair.first] = pair.second;
}
return sortedRankings;
}
int main() {
map<string, vector<int>> scores = {
{"A", {100, 80, 90, 75}},
{"B", {95, 85, 70}},
{"C", {60, 70, 80, 95, 100}},
{"D", {50, 60}},
};
map<string, int> rankings = rankParticipants(scores);
cout << "Rankings:" << endl;
for (const auto& pair : rankings) {
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}
解释:
-
rankParticipants
函数:- 接收一个包含参赛者ID和成绩列表的映射作为参数。
- 遍历参赛者数据:
- 对于每个参赛者,获取其成绩列表并按降序排序。
- 计算前3个成绩的总和。
- 如果总和大于0,则将参赛者ID和总和添加到排名映射中。
- 按排名映射中的值降序排序。
- 返回排序后的排名映射。
-
main
函数:- 创建一个包含参赛者ID和成绩列表的映射。
- 调用
rankParticipants
函数获取排名映射。 - 遍历排名映射并打印每个参赛者的排名和总分。
部署和测试:
1. 编译代码:
- 您需要使用 C++ 编译器来编译代码。
- 具体步骤取决于您使用的编译器和操作系统。
- 一般来说,您可以使用以下命令进行编译:
g++ shooting_competition.cpp -o shooting_competition
2. 运行代码:
- 您可以使用以下命令运行编译后的可执行文件:
./shooting_competition
3. 测试代码:
- 您可以检查输出的排名是否与预期一致。
- 您还可以尝试修改输入数据并观察输出如何变化。
注意:
- 您需要确保您的计算机上安装了 C++ 编译器和运行时环境。
- 您还可以使用其他 C++ 开发环境或 IDE 来编译和运行代码。
示例输出:
Rankings:
C: 275
A: 240
B: 230
D: 110
改进:
- 您可以添加错误处理机制以处理无效的输入数据。
- 您可以使用异常处理来更优雅地处理错误情况。
- 您可以将函数扩展为支持更多功能,例如打印每个参赛者的所有成绩。