本文目录导读:

简单命令行版
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class OffsideAnalysisSimple {
public static void main(String[] args) {
System.out.println("=== 反越位单刀统计系统 ===");
System.out.println("请输入比赛事件,格式为:");
System.out.println(" [球员名称] [动作]");
System.out.println("动作说明:");
System.out.println(" A - 尝试反越位插上");
System.out.println(" S - 形成单刀");
System.out.println(" F - 越位犯规");
System.out.println(" G - 进球");
System.out.println("输入 'end' 结束。");
System.out.println("-----------------------------------");
List<String[]> events = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("输入事件: ");
String input = scanner.nextLine().trim();
if ("end".equalsIgnoreCase(input)) {
break;
}
String[] parts = input.split("\\s+");
if (parts.length < 2) {
System.out.println("格式错误,请重新输入!");
continue;
}
events.add(parts);
}
scanner.close();
int successful = countSuccessful(events);
System.out.println("-----------------------------------");
System.out.println("反越位成功形成单刀次数: " + successful);
}
/**
* 统计反越位成功形成单刀的次数
* 逻辑:A触发后,下一次出现S则算1次成功,出现F则算失败
*/
public static int countSuccessful(List<String[]> events) {
int successCount = 0;
boolean attempted = false; // 是否有反越位尝试
for (String[] event : events) {
String action = event[1].toUpperCase();
if ("A".equals(action)) {
attempted = true;
} else if (attempted && "S".equals(action)) {
successCount++;
attempted = false;
} else if (attempted && "F".equals(action)) {
// 越位失败,重置状态
attempted = false;
} else if (attempted && "G".equals(action)) {
// 也统计在成功单刀后进球
successCount++;
attempted = false;
}
}
return successCount;
}
}
面向对象版(更完整)
import java.time.LocalTime;
import java.util.*;
public class OffsideAnalysis {
// 事件模型类
static class MatchEvent {
int minute; // 比赛时间(分钟)
String player; // 球员
String action; // 动作
String detail; // 描述
MatchEvent(int minute, String player, String action, String detail) {
this.minute = minute;
this.player = player;
this.action = action;
this.detail = detail;
}
@Override
public String toString() {
return String.format("[%02d'] %s - %s (%s)", minute, player, action, detail);
}
}
// 定义动作常量
static final String ACTION_ATTEMPT = "ATTACK"; // 反越位插上
static final String ACTION_ONE_ON_ONE = "ONE_ON_ONE"; // 形成单刀
static final String ACTION_OFFSIDE = "OFFSIDE"; // 越位犯规
static final String ACTION_GOAL = "GOAL"; // 进球
static final String ACTION_SAVE = "SAVE"; // 射门被扑
// 分析引擎
static class AnalysisEngine {
private int successfulCount = 0; // 成功单刀次数
private int failedCount = 0; // 失败次数
private boolean waitingForOutcome = false; // 是否在等待成功/失败
private List<MatchEvent> currentSuccessEvents = new ArrayList<>();
private List<MatchEvent> allSuccessSeq = new ArrayList<>();
public void processEvent(MatchEvent event) {
// 开始一次新的进攻尝试
if (event.action.equals(ACTION_ATTEMPT)) {
waitingForOutcome = true;
currentSuccessEvents.clear();
currentSuccessEvents.add(event);
return;
}
// 如果当前在等待结果
if (waitingForOutcome) {
currentSuccessEvents.add(event);
if (event.action.equals(ACTION_ONE_ON_ONE)) {
// 形成单刀
successfulCount++;
allSuccessSeq.addAll(new ArrayList<>(currentSuccessEvents));
printSuccessSequence(currentSuccessEvents);
waitingForOutcome = false;
} else if (event.action.equals(ACTION_OFFSIDE)) {
// 越位失败
failedCount++;
waitingForOutcome = false;
} else if (event.action.equals(ACTION_GOAL)) {
// 进球(单刀成功+1)
successfulCount++;
allSuccessSeq.addAll(new ArrayList<>(currentSuccessEvents));
printSuccessSequence(currentSuccessEvents);
waitingForOutcome = false;
} else if (event.action.equals(ACTION_SAVE)) {
// 如果没有后续动作,当作失败,但这里可以根据规则处理
// 这里简单把单刀前被扑救也视作失败
failedCount++;
waitingForOutcome = false;
}
}
}
private void printSuccessSequence(List<MatchEvent> events) {
System.out.println(" 成功序列: ");
for (MatchEvent e : events) {
System.out.println(" " + e);
}
System.out.println();
}
public void printReport() {
System.out.println("\n===== 分析报告 =====");
System.out.println("反越位成功形成单刀次数: " + successfulCount);
System.out.println("反越位失败(越位)次数: " + failedCount);
double successRate = (successfulCount + failedCount) > 0 ?
(double) successfulCount / (successfulCount + failedCount) * 100 : 0;
System.out.printf("成功率: %.1f%%\n", successRate);
}
}
public static void main(String[] args) {
// ---------- 构造测试数据 ----------
List<MatchEvent> events = new ArrayList<>();
// 模拟一场比赛
events.add(new MatchEvent(12, "梅西", ACTION_ATTEMPT, "反越位跑位"));
events.add(new MatchEvent(12, "梅西", ACTION_ONE_ON_ONE, "接到直塞,单刀面对门将"));
events.add(new MatchEvent(35, "姆巴佩", ACTION_ATTEMPT, "反越位冲入禁区"));
events.add(new MatchEvent(35, "姆巴佩", ACTION_OFFSIDE, "裁判示意越位"));
events.add(new MatchEvent(50, "C罗", ACTION_ATTEMPT, "反越位斜插"));
events.add(new MatchEvent(50, "C罗", ACTION_ONE_ON_ONE, "单刀射门"));
events.add(new MatchEvent(50, "C罗", ACTION_GOAL, "球进了!"));
events.add(new MatchEvent(67, "哈兰德", ACTION_ATTEMPT, "反越位禁区外"));
events.add(new MatchEvent(67, "哈兰德", ACTION_ONE_ON_ONE, "长驱直入"));
events.add(new MatchEvent(67, "哈兰德", ACTION_SAVE, "单刀被扑出"));
events.add(new MatchEvent(78, "萨拉赫", ACTION_ATTEMPT, "反越位切入"));
events.add(new MatchEvent(78, "萨拉赫", ACTION_ONE_ON_ONE, "形成单刀"));
events.add(new MatchEvent(78, "萨拉赫", ACTION_GOAL, "推射破门"));
events.add(new MatchEvent(89, "凯恩", ACTION_ATTEMPT, "反越位"));
events.add(new MatchEvent(89, "凯恩", ACTION_ONE_ON_ONE, "单刀打偏"));
events.add(new MatchEvent(89, "凯恩", ACTION_OFFSIDE, "实际上越位了(裁判回看VAR)"));
// ---------- 运行分析 ----------
System.out.println("========== 实时事件分析 ==========");
AnalysisEngine engine = new AnalysisEngine();
for (MatchEvent event : events) {
System.out.println("处理事件: " + event);
engine.processEvent(event);
}
engine.printReport();
// ---------- 统计所有单刀数据的原始数据也很重要 ----------
System.out.println("\n===== 所有事件记录 =====");
for (MatchEvent event : events) {
System.out.println(event);
}
}
}
运行说明
版本一使用方式:
=== 反越位单刀统计系统 ===
请输入比赛事件,格式为:
[球员名称] [动作]
动作说明:
A - 尝试反越位插上
S - 形成单刀
F - 越位犯规
G - 进球
输入 'end' 结束。
-----------------------------------
输入事件: 梅西 A
输入事件: 梅西 S
输入事件: 姆巴佩 A
输入事件: 姆巴佩 F
输入事件: end
-----------------------------------
反越位成功形成单刀次数: 1
版本二输出示例:
========== 实时事件分析 ==========
处理事件: [12'] 梅西 - ATTACK (反越位跑位)
处理事件: [12'] 梅西 - ONE_ON_ONE (接到直塞,单刀面对门将)
成功序列:
[12'] 梅西 - ATTACK (反越位跑位)
[12'] 梅西 - ONE_ON_ONE (接到直塞,单刀面对门将)
处理事件: [35'] 姆巴佩 - ATTACK (反越位冲入禁区)
处理事件: [35'] 姆巴佩 - OFFSIDE (裁判示意越位)
...
===== 分析报告 =====
反越位成功形成单刀次数: 3
反越位失败(越位)次数: 2
成功率: 60.0%
规则说明
在代码中我设定了以下规则:
- 反越位成功:球员进行插上(ATTACK)后,后续事件出现 单刀球,算作1次成功。
- 反越位失败:插上后后续出现 越位犯规,算1次失败。
- 单刀后进球与否不影响“成功”的计数,单刀本身就算成功。
- 如果要更精确,可以根据“单刀后是否进球”再进行细分,这可以通过调整逻辑实现。
如果你有更具体的统计规则(比如只看进球、只统计是否接到球等),告诉我,我可以帮你调整。