java案例统计撞墙式配合完成了几次?

wen java案例 1

篮球"撞墙式配合"统计案例(Java实现)

需求分析

撞墙式配合(Give and Go / 传切配合) 是篮球进攻中的经典配合:

java案例统计撞墙式配合完成了几次?

  • 球员A传球给球员B
  • 球员A立即切入篮下
  • 球员B回传给A完成进攻

统计目标:从传球序列中识别出"撞墙式配合"次数。


数据模型设计

/**
 * 传球事件
 */
public class PassEvent {
    private String fromPlayer;   // 传球人
    private String toPlayer;     // 接球人
    private long timestamp;      // 毫秒时间戳
    private String actionType;   // PASS(传球) / CUT(切入) / SHOT(投篮)
    public PassEvent(String fromPlayer, String toPlayer, long timestamp, String actionType) {
        this.fromPlayer = fromPlayer;
        this.toPlayer = toPlayer;
        this.timestamp = timestamp;
        this.actionType = actionType;
    }
    // getter
    public String getFromPlayer() { return fromPlayer; }
    public String getToPlayer()   { return toPlayer; }
    public long getTimestamp()    { return timestamp; }
    public String getActionType() { return actionType; }
    @Override
    public String toString() {
        return fromPlayer + " -> " + toPlayer + " [" + actionType + "] @" + timestamp;
    }
}

核心统计逻辑

判定规则:连续两次传球满足以下条件即算一次撞墙配合:

  1. 第1次:A → B (传球)
  2. 第2次:B → A (回传),且时间间隔在 阈值 内(如3秒)
import java.util.List;
public class GiveAndGoCounter {
    /** 回传时间阈值:3秒内视为同一次配合 */
    private static final long TIME_WINDOW_MS = 3000L;
    /**
     * 统计撞墙式配合次数
     */
    public static int count(List<PassEvent> events) {
        if (events == null || events.size() < 2) return 0;
        int count = 0;
        for (int i = 0; i < events.size() - 1; i++) {
            PassEvent first  = events.get(i);
            PassEvent second = events.get(i + 1);
            // 第一次必须是传球
            if (!"PASS".equals(first.getActionType())) continue;
            // A → B
            String a = first.getFromPlayer();
            String b = first.getToPlayer();
            // B → A 回传
            boolean isReturn = b.equals(second.getFromPlayer())
                            && a.equals(second.getToPlayer())
                            && "PASS".equals(second.getActionType());
            // 时间窗口内
            boolean inWindow = (second.getTimestamp() - first.getTimestamp()) <= TIME_WINDOW_MS;
            if (isReturn && inWindow) {
                count++;
                i++;  // 跳过已配对的两条事件,防止重复统计
            }
        }
        return count;
    }
}

测试案例

import java.util.Arrays;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        List<PassEvent> events = Arrays.asList(
            new PassEvent("A", "B", 1000, "PASS"),   // A→B
            new PassEvent("B", "A", 2500, "PASS"),   // B→A  ✅ 第1次撞墙
            new PassEvent("A", "C", 4000, "PASS"),
            new PassEvent("C", "A", 5000, "PASS"),   // C→A  ✅ 第2次撞墙
            new PassEvent("A", "D", 6000, "PASS"),
            new PassEvent("D", "E", 8500, "PASS"),   // 时间超3秒+非回传 ❌
            new PassEvent("E", "D", 9000, "PASS"),   // E→D  ✅ 第3次撞墙
            new PassEvent("D", "A", 11000, "PASS")
        );
        int total = GiveAndGoCounter.count(events);
        System.out.println("撞墙式配合完成次数:" + total);
    }
}

输出

撞墙式配合完成次数:3

进阶扩展

篮球位置过滤(只在特定区域发生)

增加坐标字段,判断传球是否发生在 三分线外 → 篮下 等区域。

结合追踪数据(SportVU / Hawk-Eye)

真实场景下需要:

  • 球员坐标轨迹:识别 A 传球后是否真的 向篮下切入(速度突变+方向朝向篮筐)
  • 防守人距离:判断是否为有效进攻配合

使用状态机(更严谨)

enum State { IDLE, WAIT_RETURN }
  • IDLE:记录第一次传球的 (A, B, t)
  • WAIT_RETURN:检查下一次事件是否为 B→A 且在时间窗内
  • 匹配则 count++,状态重置

处理复杂情况

  • 多次传球:A→B→C→A 算不算?(一般不算严格撞墙)
  • 投篮结束:B→A 后 A 出手,可作为一次"有效撞墙配合"加权
  • 时间窗自适应:根据节奏(Pace)动态调整阈值

完整类图

PassEvent ─────► GiveAndGoCounter
   ▲                   │
   │                   │ count()
   │                   ▼
 数据源(CSV/DB)    List<PassEvent>

要素 说明
核心特征 A→B,B→A 双向传球
关键约束 时间窗口、方向反转
算法复杂度 O(n) 单次遍历
扩展方向 坐标轨迹、区域限制、投篮联动

如果需要 读取CSV文件对接数据库可视化输出 的完整Demo,可以告诉我具体数据格式,我帮你扩展。

抱歉,评论功能暂时关闭!