/ / 2次元または3次元サブアレイ/サブ行列へのポインタ - c ++、配列、行列

2次元または3次元サブアレイ/サブ行列へのポインタ - c ++、配列、行列

次のように定義されたy(zごと)の次元の行列があるとします。

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];
}

サブ行列にアクセスするためのスマートな方法はありますか(get int**(*) (a、b(、c)]と[A、B(、C)]のサイズを持つ、データコピーなしのプレーンC ++)?

この問題の(より良いまたは悪い)グラフの例を以下に示します。

行列2dの例 ここに画像の説明を入力

回答:

回答№1は2

あなたはギザギザアレイと呼ばれるものを使用しています。 これは配列の配列であり、実行時以外にはサブ配列が同じサイズを強制することはありません。したがって、サブアレイのサイズが異なる可能性があるため、ギザギザになります。

サブマトリックスを持つためには、ギザギザの配列では、サブマトリックスのサブ配列を指すポインタのギザギザの配列が存在する必要があります。これらは一般的には存在しないので、サブアレイへのポインタの少なくともいくつかの配列を「コピーせずに」行うことはできません。

あなたのマトリックスがギザギザの配列ベースではなく、代わりに ストライド新しいサブアレイポインタ配列を割り当てることなく、サブアレイのビューを作成することができます。また、それはよりキャッシュに優しいでしょう。

非ぎざぎざの行列を作成するには、まず1次元を扱う配列ビューまたはスパンクラスを記述します。

2つのディメンションの場合、ディメンション・サイズまたはストライドのタプルを格納するためにスパン・クラスを拡張します。 [] 計算された要素への参照を返すのではなく、参照を返す次元0まで、計算された位置を指す一次元の下位スパンインスタンスを作成します。

これは非常に効率的で効率的なサブアレイを可能にしますが、数十または100行のコードが必要です。