根据矩阵形状协调转换

Zag*_*g.. 2 ruby arrays math matrix coordinates

我想将展平数组中的索引转换为多维数组中的坐标.

示例: 在以下尺寸为[3,3]的二维数组中:

[
  [ -, -, - ],
  [ *, -, - ],
  [ -, -, - ]
]
Run Code Online (Sandbox Code Playgroud)

坐标*为[0,1].如果我们将此数组展平为:

[ -, -, -, *, -, -, -, -, - ]
Run Code Online (Sandbox Code Playgroud)

坐标(或指数)*变为3.我们怎么能做相反的事情呢?也就是说,一种方法:

index_to_coordinates([3, 3], 3)  # => [0, 1]
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 5

请注意,您index_to_coordinates[3, 3](除了展平索引之外3)作为参数,但这是多余的.您需要的信息是矩阵中的每一行都是长度的3,而扁平化的索引是3.

3.divmod(3).reverse # => [0, 1]
Run Code Online (Sandbox Code Playgroud)

divmod给你一对商和余数.由于您需要订单:x坐标(余数)然后是y坐标(商),您需要reverse翻转订单.

根据问题的变化进行编辑

注意:我在下面假设ruby 1.9.我不想打扰红宝石1.8.如有必要,请自行将其翻译为ruby 1.8.应该很容易.

假设你有一个结构:

[
  [
    [0, 1, 2, 3]
    [4, 5, 6, 7]
    [8, 9, 10, 11]
  ]
  [
    [12, 13, 14, 15]
    [16, 17, 18, 19]
    [20, 21, 22, 23]
  ]
]
Run Code Online (Sandbox Code Playgroud)

这样结构的大小表示为[2,3,4].通常,我们可以将大小表示为数组sizes.您可以将此转换为一个数组flattened,该数组表示整个结构被展平到该维度时每个维度的大小:

flattened = sizes.dup.drop(1)
(1...flattened.length).reverse_each{|i| flattened[i-1] *= flattened[i]}
Run Code Online (Sandbox Code Playgroud)

通过特定示例:

flattened # => [12, 4]
Run Code Online (Sandbox Code Playgroud)

这意味着最大的循环是12,接下来是4.假设你想要坐标7.为了做到这一点,你做:

index = 7
coordinate = flattened.each_with_object([]) do |size, array|
  quotient, index = index.divmod(size)
  array.push(quotient)
end
coordinate.push(index)
Run Code Online (Sandbox Code Playgroud)

这会给你:

coordinate # => [0, 1, 3]
Run Code Online (Sandbox Code Playgroud)