【问题标题】:Algorithm for rotating image represented by array not working as expected由数组表示的旋转图像的算法未按预期工作
【发布时间】:2020-08-13 23:43:45
【问题描述】:

我正在尝试通过根据下面列出的坐标将“a”坐标处的值映射到旋转图像来旋转图像 (a)。为什么这不起作用?

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

// Desired result: 
//  rotateImage(a) =
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

// aCoords =  [[00,01,02],
//             [10, 11, 12],
//             [20,21,22]]

// rotatedImageCoordsRelatingToa = [[20, 10, 00],
//                                     [21, 11, 01],
//                                     [22,12,02]]

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = [...a]
for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        console.log("Original coordinates:" + i,j + " should map to rotated coordinates:"+ toRotateCoord, i)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}

rotateImage(a);

当我运行它时,我得到了

//[[7,4,7], 
// [8,5,4], 
// [9,4,7]]
// Not
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

我知道这可能有更好的算法,但我很好奇为什么这种方法不起作用。这似乎与访问数组的方式有关。

【问题讨论】:

标签: javascript arrays algorithm image-processing


【解决方案1】:

正如 Cris Luengo 所提到的,使用扩展运算符分配 rotateImage 似乎仍然指向内存中的同一位置。我添加了一个 for 循环来创建新数组,现在它可以工作了:

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

rotateImage(a);

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = []

for(var i = 0; i < length; i++){
        rotatedImage.push([]);
    };

for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}

【讨论】:

  • AFAIK,对象总是被引用。扩展运算符不会改变这种行为。
【解决方案2】:

问题在于,虽然rotatedImage = [...a] 创建了一个新数组,但它创建了新的子数组。因此,rotatedImageimage 共享其行。无论您分配给rotatedImage[i][j] 的任何内容都会改变image 中的行,从而影响下一些分配的结果。

为避免这种情况,请将rotatedImage 初始化为:

const rotatedImage = Array.from({length}, _ => []);

... 你的代码就可以工作了。

顺便说一句:您不需要 image 变量。由于您不打算对其进行变异,因此您可以使用a

function rotateImage(a) {
    const length = a.length;
    const rotatedImage = Array.from({length}, _ => []);
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
            rotatedImage[i][j] = a[length - (1 + j)][i];
        }
    }
    return rotatedImage;
}

let a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]];
let b = rotateImage(a);
for (let row of b) console.log(row+"")

【讨论】:

  • 太好了,感谢您的跟进,这很有意义。很难找到关于如何在不指向数组的情况下复制数组的明确答案。
猜你喜欢
  • 2021-06-01
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 2022-11-04
  • 2017-02-17
相关资源
最近更新 更多