Pushing an array into a vector

后端 未结 8 1410
一整个雨季
一整个雨季 2020-12-17 01:26

I\'ve a 2d array, say A[2][3]={{1,2,3},{4,5,6}}; and I want to push it into a 2D vector(vector of vectors). I know you can use two for loops to pus

相关标签:
8条回答
  • 2020-12-17 02:00

    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. BTW , compiling it with gcc version 4.5.0, this code produces the same assembly as

    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.

    0 讨论(0)
  • 2020-12-17 02:06

    No. The only thing you can do is leverage existing loop functions so that you only have to write one or zero of your own loops.

    0 讨论(0)
  • 2020-12-17 02:07

    The new C++0x standard defines initializer_lists which allows you to:

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

    gcc 4.3+ and some other compilers have partial C++0x support. for gcc 4.3+ you could enable c++0x support by adding the flag -std=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:

    #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());
    }
    
    0 讨论(0)
  • 2020-12-17 02:07

    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]));
      }
    }
    
    0 讨论(0)
  • 2020-12-17 02:11

    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.

    0 讨论(0)
  • 2020-12-17 02:15

    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++);
    }
    
    0 讨论(0)
提交回复
热议问题