1

C++ で構造の 2 次元ベクトルを設定してアクセスする必要があります。私の構造は次のように定義されています。

struct nodo{
  int last_prod;
  int last_slot;
  float Z_L;
  float Z_U;
  float g;
  bool fathomed;
};

ベクトルを次のように定義しました。

vector<vector<struct nodo> > n_2;

ここで、n_2 のいくつかの要素を作成する必要があります。これは再びベクトルになり、それらの単一のメンバーにアクセスします。どうすればそれを達成できますか?それは私がこれまでに持っているコードです:

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>(111-i));       
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j;
    }
}

これは機能しません。

4

7 に答える 7

3

サイズを変更するように指示するまで、または特定のサイズで初期化しない限り、ベクトルのサイズは0です。ベクトルを作成するときに、ベクトルのサイズを渡します。

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>(112-i));       
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j;
    }
}

また、0番目のインデックスをスキップしているように見えます。これは、配列の最初の値がスキップされることを意味します。それはおそらく望ましくありません。

最後に、配列が一定のサイズである場合は、std::vectorではなくstd::arrayの使用を検討してください。std::arrayはC++11の機能であり、コンパイラによっては使用できない場合があることに注意してください。

このコードを書いているとしたら、おそらく次のように書くでしょう。

#include <array>
using namespace std;

// allocate an array of 112 <struct nodo> arrays, each of size 112
array<array<struct nodo, 112>, 112> n_2;
for (int i = 0; i < 112; i++)
{
    for (int j = 0; j < 112; j++)
    {
        n_2[i][j].last_prod = j;
    }
}

または、C++11をサポートするコンパイラがない場合は次のようになります。

#include <vector>
using namespace std;

// allocate a vector of size 112 of <struct nodo> vectors, each of size 112
vector<vector<struct nodo> > n_2(112, vector<struct nodo>(112));
for (int i = 0; i < 112; i++)
{
    for (int j = 0; j < 112; j++)
    {
        n_2[i][j].last_prod = j;
    }
}

さらに理想的には、1次元のベクトルを使用し、それを2次元のベクトルとして扱う必要があります。このようにして、112の小さな割り当てではなく、一度に1つのメモリ割り当てを行うことができます。これはかなり厄介になっていますが、割り当てが遅いため、割り当ての点でO(n)ソリューションよりもO(1)ソリューションの方が優れていることは明らかです。

于 2012-02-20T16:58:08.317 に答える
0

外側のループでは、空のベクターを作成しています (更新: 質問が変更された後、空ではなくなりましたが、まだ十分な大きさではありません)。十分な大きさで作成する必要があります。

n_2.push_back(vector<struct nodo>(112-i));
于 2012-02-20T17:00:49.520 に答える
0

サイズ変更を使用することをお勧めします。少なくとも私にとっては、よりきれいに見えます。

n_2.resize(112);
for(int i = 1; i < 112; i++){
    n_2[i].resize(112- i);  
    for(int j = 1; j < 112 - i; j++){
      n_2[i][j].last_prod = j;
    }
}
于 2012-02-20T17:03:01.033 に答える
0

まず第一に、これはあまり良い方法ではありません。次元が事前にわかっている場合は、この時点で通常の 2 次元配列を使用することをお勧めします。または、「C++」のままにするために、ベクトルを何かでラップして、よりわかりやすいインターフェイスを提供できます。

第 2 に、イテレータを使用せずにベクトルに直接アクセスする場合は、配列のインデックスを 0 から開始する必要があります。

しかし、本当にこれを行いたい場合、問題は、要素を参照する前にベクターを設定する必要があることです。

そう、

n_2.push_back(vector<struct nodo>());
n_2[0].push_back(nodo());

//You can now access n_2[0][0] as there is a single nodo element in there.

要素が存在する位置にアクセスする前に、ネストされたベクターに要素を追加したことを確認する必要があります。したがって、コードは次のようになります。

for(int i=0;i<112;i++){
    n_2.push_back(vector<struct nodo>());       
    for(int j=0;j<112-i;j++){
      //At n_2[i] which we made above, add another nodo.
      n_2[i].push_back(nodo());
    }
}
于 2012-02-20T17:01:04.850 に答える
0

最初に注意する必要があるのは、(両方のサイクルで) 1 ではなく 0 から開始する必要がある開始インデックスです。

もう 1 つのことは、(演算子 [] を使用して) アドレス指定するために、ネストされたベクター内に何かをプッシュする必要があることです。

于 2012-02-20T17:05:34.640 に答える
0
for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>(111-i)); 
    // Here you only have n_2[0] ... n_2[i-1] ( the last pushed is n_2[i-1] )
    // So n_2[i] will be out of range
    // And for n_2[i-1], you only have n_2[i-1][0] ... n_2[i-1][110-i]
    // So be careful of the j's value    
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j;
    }
}
于 2012-02-20T17:07:32.813 に答える
0

まだ存在しないアイテムにアクセスしようとしています。

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>()); <--allocates an empty vector    
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j; <-- accesses indexes in the empty vector
    }
}

事前にベクター内の項目を割り当てるか、必要に応じて作成してください。とにかくベクトルのサイズを変更しないため、ベクトルの代わりに配列を使用することをお勧めします。これにより、パフォーマンスが向上します。

于 2012-02-20T17:08:59.940 に答える