You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

环形数组聚类分析:聚类数量、最大/平均聚类大小计算及代码优化

嘿,我来帮你搞定这个环形数组的聚类计算问题!首先得明确咱们的核心需求:环形数组(首尾相连)里,聚类是指连续包含2个及以上1的组,要算出三个指标:最大聚类大小、聚类数量、平均聚类大小。你给的isCluster方法只是个起步,咱们得把整个逻辑补全才能准确统计这些指标。

核心思路拆解

要处理环形数组的聚类,关键是解决两个问题:

  • 正常遍历数组时统计连续1的段
  • 处理首尾相连的特殊情况(比如数组开头和结尾都是1,要把这两段合并判断是否构成聚类)

我直接给你写完整的实现代码,同时解释每一步的逻辑:

public class RingClusterAnalyzer {
    private static int[] table;

    public static void main(String[] args) {
        // 用你给的示例数组测试:1 1 0 0 1 1 0 1 1 1
        table = new int[]{1, 1, 0, 0, 1, 1, 0, 1, 1, 1};
        analyzeClusters();
    }

    private static void analyzeClusters() {
        if (table == null || table.length == 0) {
            System.out.println("数组为空,无法计算聚类指标");
            return;
        }

        int n = table.length;
        int currentClusterSize = 0;
        int clusterCount = 0;
        int maxClusterSize = 0;
        int totalClusterElements = 0;

        // 第一步:遍历数组,统计非环形场景下的有效聚类
        for (int i = 0; i < n; i++) {
            if (table[i] == 1) {
                currentClusterSize++;
            } else {
                // 遇到0,检查当前连续1的长度是否满足聚类要求(≥2)
                if (currentClusterSize >= 2) {
                    clusterCount++;
                    totalClusterElements += currentClusterSize;
                    maxClusterSize = Math.max(maxClusterSize, currentClusterSize);
                }
                currentClusterSize = 0;
            }
        }

        // 第二步:处理环形数组的首尾相连情况
        // 先统计开头连续1的数量和结尾连续1的数量
        int startConsecutiveOnes = 0;
        while (startConsecutiveOnes < n && table[startConsecutiveOnes] == 1) {
            startConsecutiveOnes++;
        }
        int endConsecutiveOnes = 0;
        while (endConsecutiveOnes < n && table[n - 1 - endConsecutiveOnes] == 1) {
            endConsecutiveOnes++;
        }

        if (table[0] == 1 && table[n - 1] == 1) {
            // 首尾都是1,需要判断合并后的段是否构成有效聚类
            int mergedSize = startConsecutiveOnes + endConsecutiveOnes;
            if (endConsecutiveOnes >= 2) {
                // 结尾的连续1已经被统计为一个聚类,若开头的也符合要求,需要合并两个聚类
                if (startConsecutiveOnes >= 2) {
                    clusterCount--;
                    totalClusterElements += startConsecutiveOnes;
                    maxClusterSize = Math.max(maxClusterSize, mergedSize);
                }
            } else {
                // 结尾的连续1单独不够2,但合并后可能符合要求
                if (mergedSize >= 2) {
                    if (startConsecutiveOnes >= 2) {
                        // 开头的聚类已经统计过,替换成合并后的聚类
                        clusterCount--;
                        totalClusterElements -= startConsecutiveOnes;
                        totalClusterElements += mergedSize;
                        maxClusterSize = Math.max(maxClusterSize, mergedSize);
                    } else {
                        // 首尾单独都不够,合并后符合,新增一个聚类
                        clusterCount++;
                        totalClusterElements += mergedSize;
                        maxClusterSize = Math.max(maxClusterSize, mergedSize);
                    }
                }
            }
        } else {
            // 首尾不相连,检查最后一段连续1是否符合聚类要求(遍历结束时可能没统计)
            if (currentClusterSize >= 2) {
                clusterCount++;
                totalClusterElements += currentClusterSize;
                maxClusterSize = Math.max(maxClusterSize, currentClusterSize);
            }
        }

        // 计算平均聚类大小,支持小数或取整
        double averageSize = clusterCount == 0 ? 0 : (double) totalClusterElements / clusterCount;

        // 输出结果(和示例的预期结果一致)
        System.out.println("聚类数量:" + clusterCount);
        System.out.println("最大聚类大小:" + maxClusterSize);
        System.out.printf("平均聚类大小:%.1f(或取整为%d)\n", averageSize, (int) averageSize);
    }
}

代码逻辑说明

  1. 基础遍历统计:遍历数组时,追踪当前连续1的长度,遇到0就检查是否形成有效聚类,更新统计指标。
  2. 环形边界处理:专门统计开头和结尾的连续1数量,判断首尾相连时是否需要合并成一个聚类,避免重复统计或漏统计。
  3. 指标计算:最后根据总元素数和聚类数量计算平均值,同时处理聚类数量为0的边界情况。

关于你原来的isCluster方法

你原来的方法只判断了table[i]和table[i+1]是否都是1,但这个逻辑有两个问题:

  • 没处理环形数组的最后一个元素(i = n-1时i+1会越界)
  • 只能判断相邻两个是1,无法直接用来统计完整的聚类段

如果要完善这个方法,可以调整成判断某个位置是否属于一个聚类,或者判断当前连续段是否是聚类,但实际统计时,直接用上面的整体遍历方法会更高效准确。

运行上面的代码,输入示例数组会输出:

聚类数量:2
最大聚类大小:5
平均聚类大小:3.5(或取整为3)

完全符合你给出的预期结果!

内容的提问来源于stack exchange,提问作者Ozymandias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:41:06