обработка 2-мерного вектора с ++ - PullRequest
1 голос
/ 20 февраля 2012

Мне нужно настроить и получить доступ к двумерному вектору структуры в C ++. Моя структура определяется как:

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

, который не работает.

Ответы [ 7 ]

3 голосов
/ 20 февраля 2012

Вектор имеет размер 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 :: array вместо std :: vector. Обратите внимание, что 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;
    }
}

Еще лучше, если вы используете одномерный вектор и просто рассматриваете его как двумерный вектор. Таким образом, вы можете сделать одно выделение памяти одновременно, а не 112 меньших выделений. Это выглядит довольно придирчиво, но очевидно, что решение O (1) лучше, чем решение O (n), которое лучше, чем решение O (n ^ 2) с точки зрения распределения, поскольку распределение медленное.

0 голосов
/ 20 февраля 2012

Вы пытаетесь получить доступ к элементам, которые еще не существуют.

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

Либо выделите элементы в векторе заранее, либо создайте их по мере необходимости. Лучшей альтернативой является использование массива вместо вектора, так как вы все равно не изменяете размер вектора. Это улучшит производительность.

0 голосов
/ 20 февраля 2012
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;
    }
}
0 голосов
/ 20 февраля 2012

Первое, на что вы должны обратить внимание, это начальный индекс, который (в обоих циклах) должен начинаться с 0 вместо 1.

Другое дело, что вы должны вставить что-то внутрь вложенного вектора, чтобы обратиться к нему (с оператором []).

0 голосов
/ 20 февраля 2012

Я бы порекомендовал вам использовать изменения размера, по крайней мере, для меня это выглядит аккуратно:

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;
    }
}
0 голосов
/ 20 февраля 2012

Прежде всего, это не очень хороший способ сделать это. На самом деле, я бы посоветовал вам использовать обычный двумерный массив, если вы заранее знаете размеры. Или, чтобы остаться "C ++", вы можете обернуть векторы во что-то и обеспечить более понятный интерфейс.

Во-вторых, вы должны действительно начать индексы массива с 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());
    }
}
0 голосов
/ 20 февраля 2012

Во внешнем цикле вы создаете пустой вектор (ОБНОВЛЕНИЕ: после изменения вопроса он больше не пуст, но все еще недостаточно велик);вам нужно создать его с достаточно большим размером:

n_2.push_back(vector<struct nodo>(112-i));
...