根据输入的动态二维数组

sky*_*oor 4 c++ vector matrix multidimensional-array

我需要从用户获得输入N并生成N*N矩阵.我该如何申报矩阵?一般来说,数组和矩阵的大小应该在声明中固定,对吧?怎么样vector<vector<int>>?我从来没有使用过这个,所以我需要老兵的建议.

Jer*_*fin 19

A vector<vector<int>>(注意其中的空间vector<vector<int> >)可以很好地工作,但它不一定是最有效的方法.另一个可以很好地工作的是一个包含单个向量的包装器,它跟踪所表示的矩阵的"形状",并提供一个函数或重载操作符来访问数据:

template <class T>
class matrix { 
    int columns_;
    std::vector<T> data;
public:
    matrix(int columns, int rows) : columns_(columns), data(columns*rows) {}

    T &operator()(int column, int row) { return data[row*columns_+column]; }
};
Run Code Online (Sandbox Code Playgroud)

请注意,C++标准只允许operator[]使用单个操作数,因此您不能将它用于此作业,至少直接使用它.在上面的例子中,我(显然已经)使用了operator(),所以下标看起来更像Fortran或BASIC,而不是你习惯于C++.如果你真的开始使用[]表示法,你仍然可以这样做,虽然它有点棘手(你在矩阵类中重载它以返回一个代理,然后让代理类也重载operator[]以返回(引用)正确的元素 - 它内部有点丑陋,但无论如何都能很好地运作).

编辑:因为我有它躺着,这是一个如何实现后者的例子.我在大多数编译器包含之前写了这个(很长一段时间)operator[],所以它静态地分配一个数组而不是使用向量.它也适用于3D情况(因此涉及两个级别的代理),但运气方面,无论如何基本想法都会出现:

template<class T, int size>
class matrix3 {

    T data[size][size][size];

    friend class proxy;
    friend class proxy2;

    class proxy { 
        matrix3 &m_;
        int index1_, index2_;
    public:
        proxy(matrix3 &m, int i1, int i2) 
            : m_(m), index1_(i1), index2_(i2) 
        {}

        T &operator[](int index3) { 
            return m_.data[index1_][index2_][index3];
        }
    };

    class proxy2 { 
        matrix3 &m_;
        int index_;
    public:
        proxy2(matrix3 &m, int d) : m_(m), index_(d) { }

        proxy operator[](int index2) { 
            return proxy(m_, index_, index2);
        }
    };
public:
    proxy2 operator[](int index) {
        return proxy2(*this, index);
    }
};
Run Code Online (Sandbox Code Playgroud)

使用此方法,您可以使用常规C++语法处理数组,例如:

matrix3<double, size> m;

for (int x=0; x<size; x++)
    for (int y = 0; y<size; y++)
        for (int z = 0; z<size; z++)
            m[x][y][z] = x*100 + y * 10 + z;
Run Code Online (Sandbox Code Playgroud)

  • @Murali:基本上,你在几个方面都效率低下.首先,即使所有子矢量(可以说)都是相同的大小,每个子矢量都存储自己的长度.其次,使用指向动态分配数据的指针(至少通常)实现向量,因此使用向量向量,需要经过两级指针才能获得实际数据.使用单个向量代替乘法,这曾经是一个不好的权衡,但CPU比内存更快,现在几乎总是一个胜利(额外的CPU时间与额外内存访问的可能性). (3认同)
  • @MSN:你可以 - "valarray"是我过去曾多次提到的东西,但坦率地说,这是一个我决定放弃挥手的旗帜,可以这么说.简单地使用它可能有意义,但是当你进入slice,gslice,slice_array等时,它对于至少99%的C++社区来说变得完全不透明.更糟糕的是,它真的是为矢量处理器设计的; 它相对缓存不友好,所以即使你知道它在做什么,读者也这样做,无论如何它通常都是一种效率低下的方式. (3认同)
  • 您还可以使用std :: valarray,因为它已经支持各种子集访问机制. (2认同)