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

如何高效生成多维数组连续true值分组数值(仿Picross游戏)

问题

我有一个根据用户输入数字生成的多维数组,其中每个元素随机赋值为true或false,示例数组如下:

array [
   [true, false, false, true, true],
   [false, false, false, false, true],
   [true, true, true, false, false],
   [false, true, true, false, true],
   [true, false, true, true, true]
]

我希望仿照Picross游戏的样式,为该数组的每行和每列生成连续true值的分组数值,示例效果如下:

array [
         1
         1                   1     2
         1      2     3      1     2
   1 2 [true, false, false, true, true],
     1 [false, false, false, false, true],
     3 [true, true, true, false, false],
   2 1 [false, true, true, false, true],
   1 3 [true, false, true, true, true]
]

我尝试了以下代码,但未能实现需求:

for(let i = 0; i < userInput; i++) {
    array[i].forEach(element => {
        if(element == true) {
          readInt++
        } else {
          readInt = 0;
          readString += readInt + " ";
        }
    });
  }
  document.getElementById("hint1").innerHTML = readString;

请问是否有更简便的实现方法?


解决方案

1. 封装通用分组函数

不管处理行还是列,核心逻辑都是提取连续true的计数,先写一个工具函数:

// 输入一维数组,返回连续true的分组数值数组
function getTrueGroups(arr) {
  const groups = [];
  let currentCount = 0;
  for (const val of arr) {
    if (val) {
      currentCount++;
    } else {
      if (currentCount > 0) {
        groups.push(currentCount);
        currentCount = 0;
      }
    }
  }
  // 处理数组末尾的连续true
  if (currentCount > 0) {
    groups.push(currentCount);
  }
  return groups;
}

2. 生成行提示

直接遍历二维数组的每一行调用函数即可:

const rowHints = array.map(row => getTrueGroups(row));
// 示例输出:[[1,2], [1], [3], [2,1], [1,3]]

3. 生成列提示

先把数组转置(行变列),再用同样的函数处理:

// 转置二维数组:将列转为行
function transposeArray(arr) {
  return arr[0].map((_, colIndex) => arr.map(row => row[colIndex]));
}

const columnHints = transposeArray(array).map(col => getTrueGroups(col));
// 示例输出:[[1,1,1], [2], [3], [1,1], [2,1,3]]

4. 格式化对齐输出

要实现Picross的对齐样式,需要计算提示的最大长度,补空格对齐:

function formatPicross(array, rowHints, columnHints) {
  // 计算行提示的最大长度,用于左侧对齐
  const maxRowHintLength = Math.max(...rowHints.map(h => h.join(' ').length));
  // 计算列提示的最大行数,用于顶部对齐
  const maxColHintRows = Math.max(...columnHints.map(h => h.length));

  let output = "array [\n";
  // 先输出列提示
  for (let i = 0; i < maxColHintRows; i++) {
    // 留出行提示的位置
    output += ' '.repeat(maxRowHintLength + 2);
    // 遍历每一列的提示,按单元格宽度对齐
    columnHints.forEach(hint => {
      const num = hint[i] || '';
      output += num.toString().padStart(6);
    });
    output += "\n";
  }

  // 输出每行的提示和对应数组行
  array.forEach((row, idx) => {
    const hintStr = rowHints[idx].join(' ').padStart(maxRowHintLength);
    const rowStr = row.map(v => v.toString()).join(', ');
    output += `  ${hintStr} [${rowStr}],\n`;
  });

  output += "]";
  return output;
}

// 调用示例
console.log(formatPicross(array, rowHints, columnHints));

原代码的问题

  • 遇到false时把重置后的0加入字符串,逻辑错误,应该在连续true中断时记录之前的计数
  • 没有处理数组末尾的连续true(比如最后一个元素是true的情况)
  • 所有行的提示会拼接在一起,没有区分每行
  • 完全没处理列的提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:40:43