java案例统计克鲁伊夫转身做了几次?

wen java案例 4

本文目录导读:

java案例统计克鲁伊夫转身做了几次?

  1. 方案一:简单字符串匹配(如果动作是连续字符串)
  2. 方案二:状态机模拟(更符合实战逻辑)
  3. 方案三:复杂形态(包含“拨球”和“拉球”)
  4. 运行结果说明

这是一个关于统计克鲁伊夫转身(Cruyff Turn)次数的经典Java编程案例,通常这个案例用于教学,核心是状态机模式识别的思维。

由于“克鲁伊夫转身”在足球中是一个连贯动作(先拉球,再变向),在程序模拟中,它通常被定义为一组特定动作序列

通用规则定义: 如果你有一个动作字符串("左右左左右""A-B-A" 模式),我们统计这个特定模式出现了多少次。


简单字符串匹配(如果动作是连续字符串)

假设我们用字母代表动作:

  • A = 左脚拉球
  • B = 右脚拉球
  • 转身定义为:触球脚迅速切换到另一只脚,即 "AB""BA" 的连续组合,但更严格的定义是 “拉球 + 转身” 两个动作的连续。

Java代码示例(统计"AB"模式):

public class CruyffTurnCounter {
    public static void main(String[] args) {
        // 示例动作序列:L代表左脚,R代表右脚
        String actions = "LRLRLLRRLR";
        // 定义克鲁伊夫转身模式:左脚拉球后紧接右脚(LR)或右脚拉球后紧接左脚(RL)
        String pattern1 = "LR";
        String pattern2 = "RL";
        int count = countOccurrences(actions, pattern1) + countOccurrences(actions, pattern2);
        System.out.println("克鲁伊夫转身次数: " + count);
    }
    // 统计子串出现次数(不重叠)
    public static int countOccurrences(String text, String pattern) {
        int count = 0;
        int index = 0;
        while ((index = text.indexOf(pattern, index)) != -1) {
            count++;
            index += pattern.length(); // 移动到模式之后,避免重复计算
        }
        return count;
    }
}

状态机模拟(更符合实战逻辑)

如果动作是时时生成的(例如从传感器读取),你需要检测上一次动作当前动作是否构成转身。

Java代码示例(实时状态检测):

public class RealTimeCruyffCounter {
    // 定义动作常量(模拟)
    enum Action {
        LEFT_TOUCH,   // 左脚触球
        RIGHT_TOUCH,  // 右脚触球
        TURN,         // 转向动作(通常这个不单独算,是结果)
        DRIBBLE       // 普通带球
    }
    public static void main(String[] args) {
        // 模拟动作流(数组)
        Action[] actionStream = {
            Action.DRIBBLE,
            Action.LEFT_TOUCH,
            Action.RIGHT_TOUCH,   // 这里 RIGHT_TOUCH 紧接 LEFT_TOUCH,算一次转身
            Action.DRIBBLE,
            Action.RIGHT_TOUCH,
            Action.LEFT_TOUCH,    // 这里 LEFT_TOUCH 紧接 RIGHT_TOUCH,算一次
            Action.LEFT_TOUCH,
            Action.RIGHT_TOUCH    // 再算一次
        };
        int cruyffCount = 0;
        Action previousAction = null;
        for (Action currentAction : actionStream) {
            // 关键逻辑:如果上一次是左脚,这次是右脚(或反之),则计为转身
            if (previousAction != null && 
                ((previousAction == Action.LEFT_TOUCH && currentAction == Action.RIGHT_TOUCH) ||
                 (previousAction == Action.RIGHT_TOUCH && currentAction == Action.LEFT_TOUCH))) {
                cruyffCount++;
                System.out.println("检测到一次转身!");
            }
            // 更新上一步状态(只关注触球脚,忽略 DRIBBLE)
            if (currentAction == Action.LEFT_TOUCH || currentAction == Action.RIGHT_TOUCH) {
                previousAction = currentAction;
            }
        }
        System.out.println("总计: " + cruyffCount + " 次克鲁伊夫转身");
    }
}

复杂形态(包含“拨球”和“拉球”)

更进阶的模拟中,转身包含三个子动作:拉球 (Pull)转身 (Turn)拨球 (Push)。 此时需要检测三个连续状态的匹配。

public class AdvancedCruyffTurn {
    public static void main(String[] args) {
        // 动作编码:1=拉左,2=拉右,3=转身,4=拨右,5=拨左
        int[] sequence = {1, 3, 4, 1, 3, 5, 2, 3, 4};
        // 定义克鲁伊夫转身模板
        int[][] patterns = {
            {1, 3, 4}, // 拉左 -> 转身 -> 拨右
            {2, 3, 5}  // 拉右 -> 转身 -> 拨左
        };
        int count = 0;
        for (int i = 0; i < sequence.length - 2; i++) {
            int[] window = {sequence[i], sequence[i+1], sequence[i+2]};
            if (matches(window, patterns[0]) || matches(window, patterns[1])) {
                count++;
                i += 2; // 跳过已匹配的部分
            }
        }
        System.out.println("高级统计结果:" + count);
    }
    private static boolean matches(int[] a, int[] b) {
        return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
    }
}

运行结果说明

如果你运行上面的代码,会得到不同的输出,因为输入数据不同。

关键点总结:

  • 如果是字符串:用 indexOf 或正则表达式。
  • 如果是状态流:用 previousAction 变量进行状态比较。
  • 如果是多步动作:用滑动窗口比较数组。

你可以根据你的实际数据格式(是文本、数组还是实时流)选择合适的方案,如果你有具体的动作数据格式,可以发给我,我帮你写一个精确的统计逻辑。

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