lua中,多維陣列與一維陣列的相互轉換
阿新 • • 發佈:2018-11-21
探究多維陣列與一維陣列的轉換是有實際意義的,
如:
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)