Преобразование координат по форме матрицы - PullRequest
2 голосов
/ 09 мая 2011

Я хотел бы преобразовать индекс в уплощенном массиве в координату в многомерном массиве.

Пример: В следующем двухмерном массиве, размер которого равен [3, 3]:

[
  [ -, -, - ],
  [ *, -, - ],
  [ -, -, - ]
]

координата * равна [0, 1].Если мы сгладим этот массив как:

[ -, -, -, *, -, -, -, -, - ]

, то координата (или индекс) для * становится равной 3. Как мы можем сделать обратное?То есть такой метод, как:

index_to_coordinates([3, 3], 3)  # => [0, 1]

1 Ответ

5 голосов
/ 09 мая 2011

Обратите внимание, что ваш index_to_coordinates принимает [3, 3] (в дополнение к сглаженному индексу 3) в качестве аргумента, но это избыточно.Вам нужна информация о том, что каждая строка в матрице имеет длину 3, а сглаженный индекс 3.

3.divmod(3).reverse # => [0, 1]

divmod дает вам пару фактор и остаток.Поскольку вы ожидаете порядок: x-координата (остаток), а затем y-координата (частное), вам нужно reverse, чтобы перевернуть порядок.

Отредактировано в соответствии с изменением в вопросе

Примечание: я предполагаю, что рубин 1.9 в следующем.Я не хочу беспокоиться о ruby ​​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]
  ]
]

, так что размер этой структуры представлен как [2, 3, 4].В общем, мы можем выразить размер в виде массива sizes.Вы можете преобразовать это в массив flattened, который представляет размер каждого измерения, когда вся структура сглаживается до этого измерения:

flattened = sizes.dup.drop(1)
(1...flattened.length).reverse_each{|i| flattened[i-1] *= flattened[i]}

С конкретным примером:

flattened # => [12, 4]

Это означает, что самый большой цикл равен 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)

Это даст вам:

coordinate # => [0, 1, 3]
...