2

当我有一个数组(1D、2D、3D 或更多维度)时,我希望能够将索引(来自这个扁平数组)转换为它的坐标。

例如,考虑*正方形:

3D 数组([2,3,2] 形状)

arr = [ [ [ nil, nil ],
          [ nil, nil ],
          [ nil, nil ] ],
        [ [ "*", nil ],
          [ nil, nil ],
          [ nil, nil ] ] ]

arr.flatten[6]           # => "*"
arr.index2coordinates(6) # => [1,0,0] or [1][0][0]

4D 数组([2,3,1,2] 形状)

arr = [ [ [ [ nil, nil ],
            [ nil, "*" ],
            [ nil, nil ] ] ],
        [ [ [ nil, nil ],
            [ nil, nil ],
            [ nil, nil ] ] ] ]

arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [0,0,1,1] or [0][0][1][1]

一维数组([5] 形状)

arr = [ nil, nil, nil, "*", nil ]

arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [3]

我们怎么能做这样的Array#index2coordinates方法?从某种意义上说,这个问题与Convert vector to integer问题的逆题。非常感谢。

4

2 回答 2

3

示例,一步一步:

# 3D array (of [2,3,2] shape)
arr.flatten[6]           # => "*"
arr.index2coordinates(6) # => [1,0,0] or [1][0][0]

6 % 2              # => 0

(6 / 2) % 3        # (3) % 3 => 0

((6 / 2) / 3) % 2  # ((3) / 3) %2 => 1 % 2 => 1


# 4D array (of [2,1,3,2] shape)    
arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [0,0,1,1] or [0][0][1][1]

3 % 2                     # => 1

(3 / 2) % 3               # => 1 % 3 => 1

((3 / 2) / 3) % 1         # => 1 % 1 => 0

(((3 / 2) / 3) / 1) % 2   # 0 % 2 => 0

第二个示例的简单代码

result = []
index = 3

[2,1,3,2].reverse.each do |dimension|
  result = [index % dimension] + result
  index = (index / dimension)
end

result          # => [0, 0, 1, 1]
于 2012-05-08T20:19:56.303 回答
0

当您进入每个步骤时,尝试通过构建 n 维索引的结构进行递归搜索,如果/当您找到*目标时返回索引:

def coord(space, target='*', idx=[])
  found = nil
  space.each_with_index do |x,i|
    found = if x.is_a?(Array)
      coord(x, target, idx + [i])
    elsif x == target
      idx + [i]
    end
    break found if found
  end
  found
end

coord(arr3d) # => [1, 0, 0]
coord(arr4d) # => [0, 0, 1, 1]
coord(arr1d) # => [3]
coord([]) # => nil
于 2012-05-08T20:34:17.250 回答