【问题标题】:Pushing an array into a vector将数组推入向量
【发布时间】:2010-12-27 20:22:44
【问题描述】:

我有一个二维数组,比如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.

我知道这不是一个正确的代码,但我只是为了理解目的。谢谢

【问题讨论】:

    标签: c++ vector


    【解决方案1】:

    新的 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 vector v; v += 1,2,3;
    • 我期待 vector &lt;vector &lt;int&gt;&gt; a (matrix.size(), vector&lt;int&gt;(matrix[0].size(),0)); 矩阵是一个预先存在的二维向量工作。但事实并非如此。 !
    【解决方案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);
    

    用不同类型的二维数组编译应该不是很难。

    【讨论】:

      【解决方案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);
      

      【讨论】:

        【解决方案4】:

        如果要将数据推入向量的向量中,则必须编写如下内容:

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

        【讨论】:

          【解决方案5】:

          这有点作弊,但你可以利用vector constructor 为你做一个循环:

          #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。如果您更改其中的 ither 的值,您还需要更改其他地方的代码(如初始化列表)。总是喜欢让编译器为你完成工作。
          • @Martin York:就像离开第一个维度的界限,然后即时计算它?这不是一个坏主意,但鉴于我们必须指定一些维度,将它们全部明确说明似乎是合理的。
          【解决方案6】:

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

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

          实用吗?绝对不是。

          【讨论】:

            【解决方案7】:

            嗯...我可以给出部分答案,但不能给出完整答案。

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

            【讨论】:

              【解决方案8】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-03-10
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多