Вставка массива в вектор - PullRequest
4 голосов
/ 27 декабря 2010

У меня есть двумерный массив, скажем, A[2][3]={{1,2,3},{4,5,6}};, и я хочу вставить его в двухмерный вектор (вектор векторов).Я знаю, что вы можете использовать два for loops, чтобы вставить один элемент на первый вектор, а затем вставить его в другой вектор, который делает его двумерным вектором, но мне было интересно, есть ли способ в C ++ сделать это водин циклНапример, я хочу сделать что-то вроде этого:

myvector.pushback(A[1]+3); // where 3 is the size or number of columns in the array.

Я понимаю, что это неправильный код, но я поставил это только для понимания цели.Спасибо

Ответы [ 8 ]

4 голосов
/ 27 декабря 2010

Новый стандарт C ++ 0x определяет initializer_lists, что позволяет:

vector<vector<int>> myvector = {{1,2,3},{4,5,6}};

gcc 4.3+ и некоторые другие компиляторы имеют частичную поддержку C ++ 0x. для gcc 4.3+ вы можете включить поддержку c ++ 0x, добавив флаг -std=c++0x

Это не лучший способ представить ваши статические данные таким образом. Однако, если ваш поставщик компиляторов поддерживает C ++ tr1, вы можете сделать:

#include <tr1/array>  // or #include <array>
...

typedef vector<vector<int> > vector2d;
vector2d myvector;

// initialize the vectors
myvector.push_back(vector<int>());
myvector.push_back(vector<int>());

typedef std::array<std::array<int, 3>, 2> array2d;
array2d array = {{1,2,3},{4,5,6}};
array2d::const_iterator ai = array.begin(), ae = array.end();
for (vector2d::iterator i = myvector.begin(), e = myvector.end()
    ; i != e && ai != ae
    ; i++, a++)
{
    // reserve vector space
    i->reserve(array.size());

    // copy array content to vector
    std::copy(ai.begin(), ai->end(), i->begin());
}
2 голосов
/ 28 декабря 2010

Это немного сложно, но вы можете использовать рекурсию шаблона, чтобы помочь вам выполнить задание почти полностью во время компиляции. Я понимаю, что это не совсем то, что вы ищете, но я думаю, что это стоит: -)

Вот код:

#include <vector>

using namespace std;

typedef vector<vector<int> > vector2d;

template<size_t K, size_t M, size_t N>
struct v_copy {
    static void copy(vector2d& v, int(&a)[M][N])
    {
        v[K - 1].assign(a[K - 1], a[K - 1] + N);
        v_copy<K - 1, M, N>::copy(v, a);
    }
};

template<size_t M, size_t N>
struct v_copy<1, M, N> {
    static void copy(vector2d& v, int(&a)[M][N])
    {
        v[0].assign(a[0], a[0] + N);
    }
};

template<size_t M, size_t N>
void copy_2d(vector2d& v, int(&a)[M][N])
{
    v_copy<M, M, N>::copy(v, a);
}

int main()
{
    int A[2][3] = {{0, 1, 2}, {10, 11, 12}};
    vector2d vector(2);

    copy_2d(vector, A);
}

ему нужна структура, потому что в C ++ вы не можете выполнять частичную специализацию функций. Кстати, компилируя его с gcc версии 4.5.0, этот код производит ту же сборку, что и

vector[1].assign(A[1], A[1] + 3);
vector[0].assign(A[0], A[0] + 3);

Не должно быть очень сложно заставить его компилироваться с различными типами двухмерных массивов.

2 голосов
/ 28 декабря 2010

Вы можете использовать vector::assign (указатели на элементы массива являются действительными итераторами):

int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
std::vector<std::vector<int> > v(2);
for (size_t i = 0; i < 2; ++i)
   v[i].assign(a[i], a[i] + 3);
1 голос
/ 27 декабря 2010

Вы можете изменить размеры векторов, а затем использовать копирование.

int A[2][3]={{1,2,3},{4,5,6}};
std::vector< std::vector<int> > vec;

vec.resize(2);
for (int i=0; i<2; i++)
{
    vec[i].resize(3);
    std::copy(A[i], A[i]+3, vec[i].begin());
}

Это практично?Определенно нет.

1 голос
/ 27 декабря 2010

Это обман, но вы можете воспользоваться векторным конструктором , чтобы сделать один из циклов для вас:

1 голос
/ 27 декабря 2010

Если вы хотите поместить данные в вектор векторов, вы должны написать что-то вроде этого:

vector<int> inner;
vector< vector<int> >outer;

...
outer.pushback(inner);

Я думаю, что нет способа сделать это за один цикл.

Если вы хотите использовать только один вектор (что-то похожее на написанное вами), то вы можете сделать это за один цикл:

int A[2][3]={{1,2,3},{4,5,6}};
int* p = A[0];
std::vector<int> inner;
std::vector< std::vector<int> >outer;

for(int i = 0; i < 6; ++i)
{
    inner.push_back(*p++);
}
0 голосов
/ 27 декабря 2010

Нет.Единственное, что вы можете сделать, - это использовать существующие функции цикла, так что вам нужно написать только один или ноль ваших собственных циклов.

0 голосов
/ 27 декабря 2010

Хм ... Я могу дать частичный ответ, но не полный.

int elementCount = 6; // I wonder if this can be done somehow with sizeof(A) * sizeof(A[0])
int* end = A + elementCount;
for(int* current = A; current < end; ++current) {
    myvector.pushback(*current);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...