首页 > 解决方案 > 二维数组javascript中的无限递归框

问题描述

我想实现一个方法 draw() 它接受 3 个参数宽度、高度、填充并返回一个表示以下形状的二维数组:

[
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2],
[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2],
[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2],
[2,0,0,2,0,0,1,1,1,1,1,1,1,1,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,0,0,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,0,0,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,1,1,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,1,1,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,0,0,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,2,0,0,0,0,0,0,2,0,0,2,0,0,2],
[2,0,0,2,0,0,1,1,1,1,1,1,1,1,0,0,2,0,0,2],
[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2],
[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2],
[2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2],
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]

我能够绘制外部框,但无法在数组内执行递归框,我的代码是

function draw(width, height, padding){
   return Array.from({length: width}, (_, row) => {
    return Array.from({length: height}, (_, col) => {
        if(width < padding/2 || height < padding/2){
          return;
        }
        if(row === 0 || row === width - 1 ){ return 1; }
        if(col === 0 || col === height - 1){ return 2; }
        return 0;
      })
    });
  }
console.log(draw(20,20,4));

我想在 JS 中复制的演示 https://infinite-peaceful-stream.herokuapp.com/draw.php

标签: javascriptarraysalgorithmrecursiondrawing

解决方案


这是一个响应三个参数变化的交互式代码段:

我保留了您使用具有 0、1 和 2 的数组的想法,并且仅在最近时刻将该矩阵转换为字符串。但您当然可以选择立即生成最终字符:

function draw(width, height, padding) {
    if (width <= padding+2 || height <= padding+2) { // Base case: innermost rectangle
        if (width <= 0 || height <= 0) return [];
        if (height < 2) return [Array(width).fill(1)];
        return [
            Array(width).fill(1),
            ...Array.from({length: height-2}, () => width < 2 ? [2] : [2, ...Array(width-2).fill(0), 2]),
            Array(width).fill(1),
        ];
    }
    return [
        Array(width).fill(1),
        ...Array.from({length: padding>>1}, () => [2, ...Array(width-2).fill(0), 2]),
        ...draw(width - padding - 2, height - padding - 2, padding).map((row,i) => 
            [2, ...Array(padding>>1).fill(0), ...row, ...Array(padding>>1).fill(0), 2]
        ),
        ...Array.from({length: padding>>1}, () => [2, ...Array(width-2).fill(0), 2]),
        Array(width).fill(1)
    ];
}

// I/O handling
let inputs = Array.from(document.querySelectorAll("input"));
let output = document.querySelector("pre");
document.addEventListener("input", refresh);

function refresh() {
    // Get input values
    let [width, height, padding] = inputs.map(input => Math.max(0, Math.round(+input.value)));
    padding = padding - (padding % 2); // Make sure it is a multiple of 2.
    let matrix = draw(width, height, padding);
    // Convert matrix of 0, 1, 2 to string
    output.textContent = matrix.map(row => row.map(i => " -|"[i]).join``).join`\n`;
}
refresh();
input { width: 4em }
pre { font-size: 8px }
Width: <input type="number" value="70">
Height: <input type="number" value="16">
Padding: <input type="number" value="2" step="2">
<pre></pre>


推荐阅读