简体   繁体   English

将数组推入向量

[英]Pushing an array into a vector

I've a 2d array, say A[2][3]={{1,2,3},{4,5,6}}; 我有一个二维数组,比如A[2][3]={{1,2,3},{4,5,6}}; and I want to push it into a 2D vector(vector of vectors). 我想将它推入2D矢量(矢量矢量)。 I know you can use two for loops to push the elements one by on on to the first vector and then push that into the another vector which makes it 2d vector but I was wondering if there is any way in C++ to do this in a single loop. 我知道你可以使用两个for loops将元素一个接一个地推到第一个向量,然后将其推入另一个向量,这使得它成为2d向量但是我想知道在C ++中是否有任何方法可以在单个向量中执行此操作环。 For example I want to do something like this: 例如,我想做这样的事情:

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

I understand this is not a correct code but I put this just for understanding purpose. 我知道这不是一个正确的代码,但我这只是为了理解目的。 Thanks 谢谢

The new C++0x standard defines initializer_lists which allows you to: 新的C ++ 0x标准定义了initializer_lists ,它允许您:

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

gcc 4.3+ and some other compilers have partial C++0x support. gcc 4.3+和其他一些编译器具有部分C ++ 0x支持。 for gcc 4.3+ you could enable c++0x support by adding the flag -std=c++0x 对于gcc 4.3+,您可以通过添加标志-std=c++0x来启用c ++ 0x支持

Its not the best way to have your static data represented like that. 它不是让静态数据表示的最佳方式。 However, if your compiler vendor supports C++ tr1 then you could do: 但是,如果您的编译器供应商支持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());
}

You can use vector::assign (pointers to array elements are valid iterators): 你可以使用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);

This is a little tricky, but you could use template recursion to help you in having the assignment done almost completely at compile-time. 这有点棘手,但您可以使用模板递归来帮助您在编译时完成任务。 I understand that's not exactly what you are looking for, but I think it's worthwhile :-) 我明白这不是你想要的,但我认为这是值得的:-)

Here's the code: 这是代码:

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

it needed a struct because in C++ you can't do partial specialization of functions. 它需要一个结构,因为在C ++中你不能对函数进行部分特化。 BTW , compiling it with gcc version 4.5.0, this code produces the same assembly as 顺便说一句,使用gcc版本4.5.0编译它,这段代码生成相同的程序集

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

It should not be very hard to have it compile with different types of 2-dimensions arrays. 使用不同类型的2维数组进行编译应该不是很难。

If you want to push the data into vector of vectors, you have to write something like this: 如果要将数据推送到向量的向量中,则必须编写如下内容:

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

...
outer.pushback(inner);

I think there is no way to do it in a single loop. 我认为没有办法在一个循环中完成它。

If you want to use just one vector (something similar like you written), then you can do it in a single loop: 如果你只想使用一个向量(类似于你编写的东西),那么你可以在一个循环中完成它:

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

It's kind of cheating, but you could take advantage of the vector constructor to do one of the loops for you: 这有点作弊,但你可以利用向量构造函数为你做一个循环:

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

You can resize vectors and then use copy. 您可以调整矢量大小,然后使用副本。

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

Is it practical? 这是实用的吗? Definetly not. 绝对不是。

Hm... I can produce a partial answer but not a full one. 嗯...我可以产生部分答案,但不能完整答案。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM