1. 程式人生 > >lua中,多維陣列與一維陣列的相互轉換

lua中,多維陣列與一維陣列的相互轉換

探究多維陣列與一維陣列的轉換是有實際意義的,
如:
1、給定一個立方體內座標、一個順序,問此座標在立方體內按此順序數,在第幾個;
2、給定一堆物體,按某一順序放在立方體的各座標上,問最後一個會放在何處?

那麼,三維要如何轉為一維陣列呢?

最容易想到的方式:維護一個遞增變數,然後遍歷,如下,

--定義一個三維陣列和一個空的一維陣列
local arr3 = {
  {{0, 1, 2, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}},
  {{0, 1, 2, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}},
};
local arr1 = {};

--可由三維陣列得
local maxI, maxJ, maxK = 2, 3, 4;

--遍歷轉換
local n = 1;
function convert()
  for i=1, maxI do
    for j=1, maxJ do
      for k=1, maxK do
        arr1[n] = arr3[i][j][k];
        n = n + 1;
      end
    end
  end
end

這樣確實沒問題,但過於粗暴。
有沒有更優雅的方式呢?答案是有!
上述方式中,一維陣列的索引n, 是可以根據 maxI, maxJ, maxK 和 i, j, k 計算出來的。

對於三維陣列,n 可表示為:

(i-1) * (maxJ * maxK) + (j-1) * maxK + k

這個式子是怎麼得來的呢?
其實非常簡單,只是當初是選用lua,繞了個彎子。因為Lua的陣列索引是從1開始(三維陣列的 i, j, k 和一維陣列的n,均要由1開始)。

如果是在其他語言中,陣列索引從0開始,是什麼樣呢?

k + j * maxK + i + maxJ * maxK

上式可以看作是,從一點開始組合成直線,再組合成面,再組合成立體。。。原來如此。。。
更高緯度都可自行腦補了。

所以,在lua中,三維陣列轉一維陣列的方法就變為了:

--定義一個三維陣列和一個空的一維陣列
local arr3 = {
  {{0, 1, 2, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}},
  {{0, 1, 2, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}},
};
local arr1 = {};

--可由三維陣列得
local maxI, maxJ, maxK = 2, 3, 4;

--遍歷
local function convert()
  for i=1, maxI do
    for j=1, maxJ do
      for k=1, maxK do
        local n = (i-1) * (maxJ * maxK) + (j-1) * maxK + k;
        arr1[n] = arr3[i][j][k];
      end
    end
  end
end

convert()

搞清上面的問題,想要一維轉三維也是一樣的。如下:

--定義一個一維陣列和一個空的三維陣列
local arr1 = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
local arr3 = {
  {{}, {}, {}},
  {{}, {}, {}},
};

--可由三維陣列得
local maxI, maxJ, maxK = 2, 3, 4;

--遍歷轉換
local function convert()
  for i=1, maxI do
    for j=1, maxJ do
      for k=1, maxK do
        local n = (i-1) * (maxJ * maxK) + (j-1) * maxK + k;
        arr3[i][j][k] = arr1[n];
      end
    end
  end
end

convert(arr1)