2017-10-28 66 views
0

說你有這樣定義維度x每Y(每Z)的矩陣:指針2或3維子陣列/子矩陣

int** tab = new int*[x]; 
for(int i=0; i<x; ++i) tab[i] = new int[y]; 

int*** tab = new int**[x]; 
for(int i=0; i<x; ++i) { 
    tab[i] = new int*[y]; 
    for(int j=0; j<y; ++y) tab[i][j] = new int[z]; 
} 

是有任何智能的方法來訪問子矩陣(得到int**(*)沒有數據複製,普通的C++),它將具有左上(前)角[a,b(,c)]和[A,B(,C)]的大小] ?

下面是(更好或更差)問題的圖形示例。

matrix 2d example enter image description here

+0

訪問子數組只能以非常有限的方式工作。看看[SO:二維數組如何存儲在內存中?](https://stackoverflow.com/q/38204677/7478597)瞭解原因。 – Scheff

+0

順便說一句。你可以用int(* pA3d)[3] [4] [5] = new int [3] [4] [5];來分配一個3d數組;但是這僅限於具有固定大小的多暗數組。對於不同的尺寸,_I_會降低多點模糊。麻煩和1昏暗的工作。陣列。如果你真的想要這個多昏暗的東西'std :: vector'可以使你的生活更輕鬆(例如'std :: vector >>'但是又一次:我寧願'std: :vector '並且自己做多偏暗索引,你可以把它作爲Eigen lib包裝在一個專用的'class MyMatrix'中。) – Scheff

+0

嗯。更好地忘記'int(* pA3d)[3] [4] [5] = new int [3] [4] [5];'。我真的不確定指向數組的指針與指向第一個元素的指針。 (雖然我記得自己有一天在好奇心的嘗試中掌握了它,但這種哭聲不絕於耳。) – Scheff

回答

2

您正在使用所謂的鋸齒狀排列。它是一個數組數組,除了運行時之外,沒有其他的東西強制子數組的大小相同。因此鋸齒狀,因爲你可能有不同的大小的子陣列。

爲了讓子矩陣也是鋸齒陣列,您需要在那裏存在指向子矩陣的子陣列的指針鋸齒陣列。這些通常不存在,所以不,你不能「不復制」至少一些指向子數組的指針數組。

如果你的矩陣不是基於鋸齒的數組,而是單個數組與stride,那麼可以在不分配新的子數組指針數組的情況下創建子數組的視圖。它也會更加緩存友好。

要編寫非鋸齒矩陣,首先編寫處理一維的數組視圖或span類。

對於兩個維度,您需要擴展span類以存儲維度大小或步幅的元組。 []而不是返回對計算元素的引用,創建一個指向計算位置的一維下跨度實例,直到返回引用的維度爲0的情況。

這將是高效的,允許高效的子陣列,但需要幾十或100行代碼才能正確使用。

+0

「大步」是我的下一個想法,但是我的答案出現在我寫下來之前。因此,我至少確定了一些錯別字,並添加了一個鏈接,因爲跨步可能不是那麼常見(如果你不知道它的用途)。 – Scheff