在不循环 c++ 的情况下对 2D 数组进行分区

Posted

技术标签:

【中文标题】在不循环 c++ 的情况下对 2D 数组进行分区【英文标题】:partition a 2D array without looping c++ 【发布时间】:2016-02-16 19:57:11 【问题描述】:

我对 c++ 相当陌生,并且正在尝试编写 strassen 算法来乘以矩阵。部分算法要求我将矩阵划分为四个部分,例如

4 5 6 7
6 7 8 9
1 2 3 4
2 3 5 6

分区:

4 5   6 7
6 7   8 9

1 2   3 4
2 3   5 6

(然后每个部分再次递归使用和分区)。我想在不循环和复制原始矩阵中的数据的情况下对矩阵进行分区(因为这将花费更多时间)。我正在阅读的书说矩阵使用'索引计算进行分区,通过原始矩阵的一系列行索引和一系列列索引识别子矩阵。我不确定这是什么意思。

另外,我不确定我应该使用二维数组还是向量?我见过很多人推荐向量,但到目前为止我已经在二维数组中编写了所有内容,所以我希望二维数组可以实现我想要的。

p.s 可以假设矩阵的维度将始终是 2 的幂并且是 nxn(正方形)。另外,我看到了很多与此类似的问题,但实际上都没有我正在寻找的解决方案。

谢谢

【问题讨论】:

循环是一种基本算法。尝试在不使用循环的情况下编写任何中等复杂性的代码,就像在不使用分号的情况下编写代码一样。循环的唯一替代方法是通过编写大量重复的意大利面条代码,手动将每个值从源矩阵移动到适当的目标矩阵的位置,来为已知固定大小的矩阵实现此过程。如果你的书告诉你不要使用循环,找另一本书学习。 【参考方案1】:

您可以创建一个矩阵类,直接支持子矩阵作为视图:

template<typename T>
struct Matrix 
    int rows, cols, stride;
    std::vector<T> data; // Possibly empty for a view
    T *ptr;

    // A fresh matrix (owning its data)
    Matrix(int rows, int cols)
        : rows(rows), cols(cols), stride(cols),
          data(rows*cols),
          ptr(&data[0])
    
    

    // A view of a sub-matrix (pointing to the original data!)
    Matrix(Matrix& m, int row0, int col0, int rows, int cols)
        : rows(rows), cols(cols), stride(m.stride),
          ptr[&m(row0, col0)]
    
    

    T& operator()(int row, int col) 
        return ptr[row*stride + col];
    

    ...
;

当然,您需要确保视图不会超过拥有矩阵,并且如果该操作未被禁止,您需要注意复制视图对象的含义。

添加诸如将视图转换为拥有矩阵之类的显式操作可能很有用(如果复制构造函数不打算这样做的话)。

【讨论】:

以上是关于在不循环 c++ 的情况下对 2D 数组进行分区的主要内容,如果未能解决你的问题,请参考以下文章

Movilizer:在不更改数组键的情况下对数据容器进行排序

如何在不使用Assembler循环的情况下对3个变量进行排序?

如何在不循环的情况下将数组的内容复制到 C++ 中的 std::vector?

python - 重复numpy数组而不复制数据

如何在不使用乘法的情况下对数字进行平方?

在不破坏顺序的情况下对列进行分组