【问题标题】:Is there a more natural way to represent a matrix of T than a vector< vector< T>>?有没有比vector<vector<T>>更自然的方式来表示T的矩阵?
【发布时间】:2014-09-20 02:25:42
【问题描述】:

上下文:

我正在尝试学习 C++(同时阅读一些 stackoverflow 社区推荐的书籍),我决定尝试制作一个具有基本功能的元胞自动机程序,只是为了学习(并且因为它对我来说很有趣)。

问题:

有没有比使用向量>更自然的方式来表示Cell元素的矩阵? 我正在标准库或其他一些流行库中寻找潜在的替代品。对性能的评论将不胜感激。

我在使用向量的向量时没有遇到问题,语法上也没有问题,我只是想知道替代方案。而且因为我没有经验,所以每次我写一些代码时,我都会想可能有很多更直接的方法可以做到,而我自己是找不到的。

这是我的第一个问题,所以如果我做了一些违反问题指南的事情,我将非常感谢您指出这一点。

有用的相关问题供将来参考:Is a vector<vector<double>> a good way to make a make a matrix class?

【问题讨论】:

  • 如果性能是一个真正的问题,那么您可能会从原始多维数组中获得更好的性能:Cell (*cells)[100] = new Cell[100][100];。原因是编译器可以使用简单的计算而不是双重取消引用来访问单元格。
  • 既然你问:不要在你的问题中包含“提前致谢”或任何形式的“谢谢”。这不是论坛。至于你的问题:考虑一个提供operator()(size_t, size_t) 的 Matrix 类——它可以随心所欲地管理它的内存,特别是避免嵌套vector 的双重间接。还有std::valarray,不过比较专业。
  • “有用的相关问题”是将vector of vectorsarray of arrays 进行比较。由于我已经概述的原因,这两种方法的效率都可能低于真正的多维数组。多维数组只需要一个取消引用,然后进行简单的计算。数组(或向量)的数组需要两次取消引用。
  • @Galik:多维数组就是数组的数组。您的意思是将其与指向数组的指针数组进行比较吗?

标签: c++ matrix vector standards


【解决方案1】:
 Matrix<double, 13, 3> 

来自 Eigen3 库 http://eigen.tuxfamily.org/dox/group__QuickRefPage.html Eigen3 几乎提供了线性代数所需的所有运算,并且经过了良好的测试和广泛的用户群使用。

【讨论】:

    【解决方案2】:

    通常有两种方法来表示二维数组。

    1. 指向其他数组的指针数组,这是std::vector&lt;std::vector&lt;T&gt;&gt; 使用的模型。

    2. 一个紧密排列的数组,在内存中包含一行接一行。然后可以在i + j * width 找到元素i, j

    C++ 中的内置多维数组有点奇怪,因为它们与 1 共享相似的语法,但类型
    T[10][10] 与我所知道的编译器实现类似 2 的方案。我不知道从如果这是标准规定的,我的头顶。

    【讨论】:

    • 多维数组必须像2一样实现。它们是数组的数组,数组必须是连续的。
    • 还可以使用智能指针管理多维数组:std::unique_ptr&lt;Cell[][100]&gt; cells(new Cell[100][100]);
    • 我喜欢#2,它带有一个易于使用的包装类。
    【解决方案3】:

    我很想做这样的事情。我不知道它可能比向量向量有多少速度优势,所以我会做一些测试来检查。不过我认为它会有一些速度优势。

    typedef int Cell;
    
    int main()
    {
        // manage the raw multidimensional array pointer in a smart pointer
        // so no need to worry about memory leaks
        std::unique_ptr<Cell[][100]> cell_uptr(new Cell[100][100]);
    
        // work from the raw pointer (maybe save a dereference?)
        Cell(*cells)[100] = cell_uptr.get();
    
        for(size_t x = 0; x < 100; ++x)
        {
            for(size_t y = 0; y < 100; ++y)
            {
                // the compiler should be able to access cells[x][y]
                // based on a simple calculation rather than a second dereference
                cells[x][y] = 0;
            }
        }
        // no need to worry about cleaning up
    }
    

    注意:这种方法的缺点是数组的size固定的 在编译时。

    【讨论】:

    • 我总是愿意学习,否决者(或其他任何人)可以解释问题吗?
    • 我没有投反对票,但这种方法的一个主要缺点是列数在编译时是固定的。
    • @Ben 是的,谢谢,我会在答案中提到这一点。
    • @Galik 我投了反对票,因为使用 C 数组会带来很多问题。它们是过去的遗物,几乎不应该被使用,根据 Bjarne Stroupstrup 的说法:youtube.com/watch?v=86xWVb4XIyE 1:17:40 是一个地方,在视频中还有其他地方他提到了他对 C 数组的厌恶(我建议观看整个视频,以了解现代 C++ 风格)。
    • @SteveM Straustrup 正在谈论“缓冲区溢出”问题并使用向量来消除它。当他们可以简单地使用向量时,没有人会使用原始缓冲区。这与这种情况无关。甚至这个特别要求 替代方法 使用std::vector 的问题。目前在标准库中没有个现代容器可以完成多维数组的工作,在这种情况下使用一个容器并没有真正的缺点(使用智能管理指针)。
    猜你喜欢
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多