将一个数组推入向量中

7

我有一个二维数组,比如A[2][3]={{1,2,3},{4,5,6}};,我想将其推入一个二维向量(向量的向量)。我知道可以使用两个for循环逐个将元素推入第一个向量,然后将其推入另一个向量,从而形成二维向量,但我想知道是否有一种方法在C++中可以在单个循环中完成此操作。例如,我想做这样的事情:

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

我知道这不是正确的代码,但我只是为了方便理解而放置的。谢谢。

8个回答

5
新的C++0x标准定义了initializer_lists,它允许你:
vector<vector<int>> myvector = {{1,2,3},{4,5,6}};

gcc 4.3+和其他一些编译器支持部分C++0x。

对于gcc 4.3+,您可以通过添加标志-std=c++0x来启用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());
}

我刚想起来了#include <boost/assign/std/vector.hpp>vector<int> v; v += 1,2,3; - langerra.com
我原本期望使用预先存在的二维向量matrix来工作,创建一个vector <vector <int>> a (matrix.size(), vector<int>(matrix[0].size(),0));。但是它并没有正常工作! - Jay D

3
你可以使用 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);

2

这有点棘手,但你可以使用模板递归来帮助你几乎完全在编译时完成分配。我知道这不完全是你想要的,但我认为这是值得的 :-)

这是代码:

#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);

将其编译为不同类型的二维数组应该不难。


1
如果你想把数据添加到向量的向量中,你需要编写类似以下代码的语句:
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++);
}

1

这有点作弊,但你可以利用向量构造器来为你完成其中一个循环:

#include <vector>

int main() {
  const int XMAX = 2, YMAX = 3;
  int A[XMAX][YMAX] = {{1,2,3}, {4,5,6}};
  std::vector<std::vector<int> > v;

  for (size_t x = 0; x < XMAX; ++x) {
    v.push_back(std::vector<int>(&A[x][0], &A[x][YMAX]));
  }
}

不喜欢在这里使用XMAX/YMAX。如果您更改其中任何一个的值,还需要更改其他地方的代码(例如初始化列表)。始终优先让编译器为您完成工作。 - Martin York
@Martin York:比如说省略第一维的边界,然后在运行时计算它?这不是一个坏主意,但考虑到我们必须指定一些维度,显式地指定所有维度似乎是合理的。 - Nate Kohl

1

您可以调整向量大小,然后使用复制功能。

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

这个实用吗?绝对不是。


0
嗯...我可以提供部分答案,但不能提供完整的答案。
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);
}

0

不行,你唯一能做的就是利用现有的循环函数,这样你只需要编写一个或零个自己的循环。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接