本文目录导读:

这是一个非常有趣的编程案例!让我为您设计一个统计“马赛回旋”使用频率的Java解决方案。
场景设定
假设我们在分析足球比赛数据或视频分析系统,需要统计球员在比赛中使用马赛回旋(一种过人技巧)的频率。
完整代码实现
基础数据模型
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
// 球员类
class Player {
private String id;
private String name;
private String team;
private String position;
public Player(String id, String name, String team, String position) {
this.id = id;
this.name = name;
this.team = team;
this.position = position;
}
// getters and setters
public String getId() { return id; }
public String getName() { return name; }
public String getTeam() { return team; }
public String getPosition() { return position; }
}
// 技术动作事件类
class SkillEvent {
private String playerId;
private String skillType; // "马赛回旋", "踩单车", "人球分过" 等
private LocalDateTime timestamp;
private int matchId;
private boolean successful; // 是否成功
public SkillEvent(String playerId, String skillType, LocalDateTime timestamp,
int matchId, boolean successful) {
this.playerId = playerId;
this.skillType = skillType;
this.timestamp = timestamp;
this.matchId = matchId;
this.successful = successful;
}
// getters
public String getPlayerId() { return playerId; }
public String getSkillType() { return skillType; }
public LocalDateTime getTimestamp() { return timestamp; }
public int getMatchId() { return matchId; }
public boolean isSuccessful() { return successful; }
}
// 统计分析结果类
class FrequencyStat {
private String playerId;
private String playerName;
private int totalAttempts; // 尝试次数
private int successfulAttempts; // 成功次数
private double successRate; // 成功率
private double perMatchFrequency; // 场均频率
private int matchCount; // 出场场次
public FrequencyStat(String playerId, String playerName) {
this.playerId = playerId;
this.playerName = playerName;
this.totalAttempts = 0;
this.successfulAttempts = 0;
this.successRate = 0.0;
this.perMatchFrequency = 0.0;
this.matchCount = 0;
}
// 更新统计
public void updateStats(boolean successful, int totalMatches) {
this.totalAttempts++;
this.matchCount = totalMatches;
if (successful) {
this.successfulAttempts++;
}
// 计算场均频率
if (totalMatches > 0) {
this.perMatchFrequency = (double) this.totalAttempts / totalMatches;
}
// 计算成功率
if (this.totalAttempts > 0) {
this.successRate = (double) this.successfulAttempts / this.totalAttempts * 100;
}
}
@Override
public String toString() {
return String.format("%-15s | 尝试: %d次 | 成功: %d次 | 成功率: %.1f%% | 场均: %.2f次",
playerName, totalAttempts, successfulAttempts, successRate, perMatchFrequency);
}
// getters
public String getPlayerId() { return playerId; }
public String getPlayerName() { return playerName; }
public int getTotalAttempts() { return totalAttempts; }
public double getPerMatchFrequency() { return perMatchFrequency; }
public int getMatchCount() { return matchCount; }
}
统计分析服务
class SkillFrequencyAnalyzer {
private Map<String, Player> players;
private List<SkillEvent> skillEvents;
private Map<String, Set<Integer>> playerMatchRecords; // 球员出场比赛记录
public SkillFrequencyAnalyzer() {
this.players = new HashMap<>();
this.skillEvents = new ArrayList<>();
this.playerMatchRecords = new HashMap<>();
}
// 添加球员
public void addPlayer(Player player) {
players.put(player.getId(), player);
playerMatchRecords.putIfAbsent(player.getId(), new HashSet<>());
}
// 记录技能事件
public void recordSkillEvent(SkillEvent event) {
skillEvents.add(event);
// 记录球员出场
playerMatchRecords.get(event.getPlayerId()).add(event.getMatchId());
}
// 统计数据(核心方法)
public List<FrequencyStat> analyzeSkillFrequency() {
Map<String, FrequencyStat> statsMap = new HashMap<>();
// 初始化所有球员的统计
for (Player player : players.values()) {
statsMap.put(player.getId(),
new FrequencyStat(player.getId(), player.getName()));
}
// 遍历所有技能事件
for (SkillEvent event : skillEvents) {
// 只统计马赛回旋
if ("马赛回旋".equals(event.getSkillType())) {
FrequencyStat stat = statsMap.get(event.getPlayerId());
if (stat != null) {
// 获取该球员的总出场次数
int totalMatches = playerMatchRecords
.getOrDefault(event.getPlayerId(), Collections.emptySet())
.size();
stat.updateStats(event.isSuccessful(), totalMatches);
}
}
}
return new ArrayList<>(statsMap.values());
}
// 获取使用频率排名TOP N
public List<FrequencyStat> getTopFrequencyPlayers(int topN) {
List<FrequencyStat> stats = analyzeSkillFrequency();
return stats.stream()
.filter(s -> s.getTotalAttempts() > 0)
.sorted((s1, s2) -> Double.compare(s2.getPerMatchFrequency(),
s1.getPerMatchFrequency()))
.limit(topN)
.collect(Collectors.toList());
}
// 多维度的统计分析
public Map<String, Object> comprehensiveAnalysis() {
Map<String, Object> result = new HashMap<>();
List<FrequencyStat> allStats = analyzeSkillFrequency()
.stream()
.filter(s -> s.getTotalAttempts() > 0)
.collect(Collectors.toList());
// 1. 场均频率最高的球员
result.put("最高场均频率", allStats.stream()
.max(Comparator.comparingDouble(FrequencyStat::getPerMatchFrequency))
.orElse(null));
// 2. 尝试次数最多的
result.put("最多尝试次数", allStats.stream()
.max(Comparator.comparingInt(FrequencyStat::getTotalAttempts))
.orElse(null));
// 3. 整体统计数据
int totalAttempts = allStats.stream()
.mapToInt(FrequencyStat::getTotalAttempts)
.sum();
double avgFrequency = allStats.stream()
.mapToDouble(FrequencyStat::getPerMatchFrequency)
.average()
.orElse(0.0);
result.put("总尝试次数", totalAttempts);
result.put("平均场均频率", avgFrequency);
result.put("参与球员数", allStats.size());
return result;
}
}
主程序演示
public class MarseilleRouletteFrequencyDemo {
public static void main(String[] args) {
// 创建分析系统
SkillFrequencyAnalyzer analyzer = new SkillFrequencyAnalyzer();
// 添加球员数据(模拟)
addSampleData(analyzer);
// 统计马赛回旋使用频率
System.out.println("========== 马赛回旋使用频率统计 ==========\n");
// 1. 查看所有球员的统计数据
List<FrequencyStat> stats = analyzer.analyzeSkillFrequency();
System.out.println("=== 所有球员的马赛回旋统计数据 ===");
stats.forEach(System.out::println);
// 2. 获取使用频率TOP5球员
System.out.println("\n=== 场均使用频率TOP5球员 ===");
List<FrequencyStat> topPlayers = analyzer.getTopFrequencyPlayers(5);
topPlayers.forEach(System.out::println);
// 3. 综合统计分析
System.out.println("\n=== 综合统计分析 ===");
Map<String, Object> comprehensive = analyzer.comprehensiveAnalysis();
comprehensive.forEach((key, value) -> {
if (value instanceof FrequencyStat) {
System.out.println(key + ": " + value);
} else {
System.out.println(key + ": " + value);
}
});
// 4. 添加额外的高级分析
advancedAnalysis(analyzer);
}
// 模拟数据
private static void addSampleData(SkillFrequencyAnalyzer analyzer) {
// 创建球员
Player player1 = new Player("P001", "梅西", "巴黎圣日耳曼", "前锋");
Player player2 = new Player("P002", "C罗", "利雅得胜利", "前锋");
Player player3 = new Player("P003", "内马尔", "利雅得新月", "边锋");
Player player4 = new Player("P004", "姆巴佩", "皇家马德里", "前锋");
analyzer.addPlayer(player1);
analyzer.addPlayer(player2);
analyzer.addPlayer(player3);
analyzer.addPlayer(player4);
// 模拟比赛数据:addSampleData方法中添加模拟事件
Random random = new Random(42); // 固定种子,保证结果可重复
// 模拟球员参加的比赛
String[] matchIds = {"M001", "M002", "M003", "M004", "M005", "M006", "M007", "M008"};
String[][] playerMatches = {
{"P001", "M001", "M002", "M003", "M004", "M005", "M006", "M007"},
{"P002", "M001", "M002", "M003", "M004", "M005"},
{"P003", "M001", "M002", "M003", "M004", "M005", "M006"},
{"P004", "M001", "M002", "M003"}
};
// 添加比赛记录和技能事件
for (String[] pm : playerMatches) {
String pid = pm[0];
for (int i = 1; i < pm.length; i++) {
// 模拟每场比赛的技能使用
int eventCount = random.nextInt(5) + 1; // 每场1-5次
for (int j = 0; j < eventCount; j++) {
boolean isMarseille = random.nextInt(3) != 0; // 2/3概率是马赛回旋
if (isMarseille) {
boolean successful = random.nextBoolean();
analyzer.recordSkillEvent(new SkillEvent(
pid,
"马赛回旋",
LocalDateTime.now(),
Integer.parseInt(pm[i].replace("M", "")),
successful
));
}
}
}
}
}
// 高级分析(简单版本,如需可继续扩展)
private static void advancedAnalysis(SkillFrequencyAnalyzer analyzer) {
// 这里可以添加更多的高级分析逻辑
System.out.println("\n=== 分析提示 ===");
System.out.println("可添加更多分析维度:");
System.out.println("- 按位置统计使用频率");
System.out.println("- 按比赛阶段(比赛时间)分析");
System.out.println("- 不同对手的战术选择分析");
System.out.println("- 赛季趋势分析");
}
}
实际应用场景
体育数据分析
- 实时统计球员技能使用情况
- 战术分析:发现哪些球员更倾向使用马赛回旋
- 比赛策略:针对高频使用球员制定防守策略
扩展可能性
- 视频分析集成:结合计算机视觉识别技巧动作
- 实时预警系统:当马赛回旋使用过多时提醒教练
- 球员评估:作为球员技术全面性的评估指标
可优化的地方
- 添加更多技能类型对比
- 引入训练强度、对手实力等因素
- 集成图形化展示(使用Chart.js或JFreeChart)
这个案例设计灵活,可以根据实际需求调整统计维度和分析深度,是一个完整、可扩展的Java数据分析示例。