13

私はC/C ++を初めて使用し、頭を悩ませてきましたが、このような「構造」を作成する方法がわかりません。

代替テキスト

ポインタを使用した3D動的配列であると想定されています。

私はこのように始めましたが、そこで立ち往生しました

  int x=5,y=4,z=3;
  int ***sec=new int **[x];

yとzの静的サイズでそれを作成する方法を知っていれば十分です。

どうか、助けていただければ幸いです。

前もって感謝します。

4

7 に答える 7

22

整数の動的な3D配列を作成するには、最初に1Dおよび2D配列を理解することをお勧めします。

1D配列:これは次の方法で非常に簡単に実行できます。

const int MAX_SIZE=128;
int *arr1D = new int[MAX_SIZE];

ここでは、整数を格納できるメモリのチャンクを指すintポインタを作成しています。

2D配列:上記の1D配列のソリューションを使用して、2D配列を作成できます。まず、最終的に実際のデータを指す他の整数ポインタのみが保持されるメモリブロックを指すポインタを作成します。最初のポインターはポインターの配列を指しているので、これはポインター間(ダブルポインター)と呼ばれます。

const int HEIGHT=20;
const int WIDTH=20;

int **arr2D = new int*[WIDTH];  //create an array of int pointers (int*), that will point to 
                                //data as described in 1D array.
for(int i = 0;i < WIDTH; i++){
      arr2D[i] = new int[HEIGHT]; 
}

3D配列:これはあなたがやりたいことです。ここでは、上記の2つのケースで使用されている両方のスキームを試すことができます。2D配列と同じロジックを適用します。問題の図はすべてを説明しています。最初の配列は、pointer-to-pointer-to-pointerになります(int ***-ダブルポインターを指すため)。解決策は次のとおりです。

const int X=20;
const int Y=20;
const int z=20;

int ***arr3D = new int**[X];
for(int i =0; i<X; i++){
   arr3D[i] = new int*[Y];
   for(int j =0; j<Y; j++){
       arr3D[i][j] = new int[Z];
       for(int k = 0; k<Z;k++){
          arr3D[i][j][k] = 0;
       }
   }
}
于 2010-10-11T08:20:46.763 に答える
11
// one-liner
typedef std::vector<std::vector<std::vector<int> > > ThreeDimensions;
// expanded
typedef std::vector<int> OneDimension;
typedef std::vector<OneDimension> TwoDimensions;
typedef std::vector<TwoDimension> ThreeDimensions;

(結局、これはc ++のタグが付けられています)

ジョーの質問に答えて編集

こんにちはまたジョー=)確かに。次に例を示します。

#include <vector>
#include <iostream>

int main(int argc, char* const argv[]) {

    /* one-liner */
    typedef std::vector<std::vector<std::vector<int> > >ThreeDimensions;
    /* expanded */
    typedef std::vector<int>OneDimension;
    typedef std::vector<OneDimension>TwoDimensions;
    typedef std::vector<TwoDimensions>ThreeDimensions;

    /*
       create 3 * 10 * 25 array filled with '12'
     */
    const size_t NElements1(25);
    const size_t NElements2(10);
    const size_t NElements3(3);
    const int InitialValueForAllEntries(12);

    ThreeDimensions three_dim(NElements3, TwoDimensions(NElements2, OneDimension(NElements1, InitialValueForAllEntries)));

    /* the easiest way to assign a value is to use the subscript operator */
    three_dim[0][0][0] = 11;
    /* now read the value: */
    std::cout << "It should be 11: " << three_dim[0][0][0] << "\n";
    /* every other value should be 12: */
    std::cout << "It should be 12: " << three_dim[0][1][0] << "\n";

    /* get a reference to a 2d vector: */
    TwoDimensions& two_dim(three_dim[1]);

    /* assignment */
    two_dim[2][4] = -1;
    /* read it: */
    std::cout << "It should be -1: " << two_dim[2][4] << "\n";

    /* get a reference to a 1d vector: */
    OneDimension& one_dim(two_dim[2]);

    /* read it (this is two_dim[2][4], aka three_dim[1][2][4]): */
    std::cout << "It should be -1: " << one_dim[4] << "\n";
    /* you can also use at(size_t): */
    std::cout << "It should be 12: " << one_dim.at(5) << "\n";

    return 0;
}
于 2010-10-11T08:06:45.567 に答える
1

あなたが試すことができます:

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

そして、このメモリの使用が終了したら、次のように割り当てを解除できます。

for(int i=0;i<x;i++) {
  for(int j=0;j<y;j++) {
    delete [] sec[i][j];
  }
  delete [] sec[i];
}
delete [] sec;
于 2010-10-11T07:52:45.047 に答える
1

包括的な答え。

これを実際にC++(ラフCではない)で記述している場合は、この複雑なデータ構造をもう一度確認する必要があると思います。あなたがやろうとしていることを念頭に置いてIMOを再設計する方が良いでしょう。

于 2010-10-11T08:16:30.960 に答える
1

あなたがやろうとしていることは、C++では慣用的ではありません。もちろん、これにはaを使用できint***pointerますが、これは強くお勧めしません。C ++では、そこに到達するためのより良い方法があります。

vector<vector<vector<int> > > foo (5,vector<vector<int> >(4, vector<int>(3)));

これにより、要求したものと同様のメモリレイアウトの結果が得られます。それはあなたの写真のように異なるサイズを持つために動的なサイズ変更と内部ベクトルをサポートします。さらに、手動での割り当てや削除について心配する必要はありません。また、ベクトルはサイズを知っているので、どこかで覚えておく必要はありません。

ただし、すべての要素が同じメモリブロックに連続して格納される「長方形」の3D配列が必要な場合は、boost::multiarrayを使用できます。

于 2010-10-11T08:46:07.740 に答える
0

OK、始めましょう

int ***sec = new int**[x]; 

secは、長さxのint **の配列になっているので、ここでは、ゼロ番目の要素を必要なものにすることに焦点を当てます。

sec[0] = new int*[y];

これで、sec[0]は長さyのint*の配列を指します。これで、ツリーの最後のビットを実行する必要があります。

sec[0][0] = new int[z];

そして最後にそれをあなたの図の形にするために

sec[0][0][z-1] = 0;

これは宿題の質問のように見えます。答えとそれが機能する理由を実際に理解していることを確認してください。

于 2010-10-11T07:43:37.517 に答える
-1

問題が発生している実際の配列の場合は、次を参照してください。多次元配列へのポインタを宣言し、配列を割り当てる

正確に何が欲しいかはわかりませんが、リンクリストについて読みたいと思うかもしれません。

于 2010-10-11T07:41:17.490 に答える