web-dev-qa-db-ja.com

2Dベクトルへの要素の挿入

そのため、隣接リストを実装するクラスを作成しています。現在、クラス定義で2つのベクトルを初期化しました。

vector<vector<int>> adjList;
vector<int> neighbors;

そして、それを作成するために使用する予定の2つの関数を宣言しました。

bool constructAdjList();
bool insertIntoAdjList(int, int);

頭を2Dベクトルに巻き付けるのが難しくなっています。それは本質的にベクトルのベクトルであることを理解していますが、「サブベクトル」の1つに新しい値を挿入する方法について混乱しています。たとえば、次のループで空の隣接リストをcreateAdjListに作成できます。

for (int i = 0; i < numOfValues; i++){
    neighbors.Push_back(0);
    adjList.Push_back(neighbors);
    neighbors.clear();
}

しかし、どのように言うと、値5をadjListの4番目のベクトルにプッシュバックします。これは、insertIntoAdjList関数で次のように表されます。

insertIntoAdjList(4, 5);

AdjList [4] [1]と言うことで、2Dベクトルの特定の値にアクセスできることはわかっていますが、どうすればその値にプッシュできますか?

ありがとう!

7
user3078735

別のベクトルの要素であるベクトルをプッシュするには、これを行うだけです

adjList[x].Push_back();
12
Kam

ここにいくつかのメモがあります。

2つのメンバーのコンストラクターを使用するだけで、ループを大幅に短縮できます。

vector<int> neighbors(1, 0); // set to length 1, value is zero
vector<vector<int>> adjList(numOfValues,neighbors); // "outer" vector is numOfValues long
.                                                   // each row is a *COPY* of neighbor

構築時にこれを行うことができない場合(おそらくnumOfValuesがまだわかっていない場合)、使用できるより良いループフレージングがまだあります。

// neighbors object can be reused
neighbors.clear(0);
neighbors.Push_back(0);
adjList.reserve(numOfValues); // reserving memory ahead of time will prevent allocations
for (int i = 0; i < numOfValues; i++){
    adjList.Push_back(neighbors); // Push_back is by *COPY*
}

あなたの例では、clearとPush_backを使用して、ループの反復ごとに基本的に同じベクトルを構築することにより、risking各反復の割り当てと割り当て解除になります。実際には、ほとんどの実装はこれを行いませんが、短縮し、潜在的に物事をより効率的にすることができれば、私たちもそうすることができます。

最後に、隣接する要素の数が比較的少なく、行ごとに類似している場合(たとえば、各要素が他の5つまで接続する四面体要素を持つ有限要素コード)、他の人が示唆しているように、別の構造を使用した方がよい場合がありますベクトルのベクトルより。たとえば、新しい「行」がN個の要素ごとに始まるように論理的に編成された単一のベクトル。

1
JHumphrey

最初にベクトルに値がない場合-値を1つのベクトルにプッシュしてから、このベクトルを2Dベクトルにプッシュできます。例えば:

  vector< vector<int> > vt1;
  vector<int> vt2;

  vt2.Push_back(value);
  vt1.Push_back(vt2);

ベクトルがすでに入力されている場合は、-

vt1[index].Push_back(value);
1
Hanu Tyagi