环形数组聚类分析:聚类数量、最大/平均聚类大小计算及代码优化
嘿,我来帮你搞定这个环形数组的聚类计算问题!首先得明确咱们的核心需求:环形数组(首尾相连)里,聚类是指连续包含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的长度,遇到0就检查是否形成有效聚类,更新统计指标。 - 环形边界处理:专门统计开头和结尾的连续
1数量,判断首尾相连时是否需要合并成一个聚类,避免重复统计或漏统计。 - 指标计算:最后根据总元素数和聚类数量计算平均值,同时处理聚类数量为0的边界情况。
关于你原来的isCluster方法
你原来的方法只判断了table[i]和table[i+1]是否都是1,但这个逻辑有两个问题:
- 没处理环形数组的最后一个元素(
i = n-1时i+1会越界) - 只能判断相邻两个是
1,无法直接用来统计完整的聚类段
如果要完善这个方法,可以调整成判断某个位置是否属于一个聚类,或者判断当前连续段是否是聚类,但实际统计时,直接用上面的整体遍历方法会更高效准确。
运行上面的代码,输入示例数组会输出:
聚类数量:2 最大聚类大小:5 平均聚类大小:3.5(或取整为3)
完全符合你给出的预期结果!
内容的提问来源于stack exchange,提问作者Ozymandias
相关产品推荐
相关产品推荐

