2

我有一个问题,想知道是否有人可以提供理想的解决方案。

基本上(小数据)但是,如果我有这样的矩阵:

     0 1 0 0
     1 1 1 0
     0 0 0 0
     1 1 0 0

然后我需要将此矩阵拆分为与第二个矩阵大小相同的块,在本例中为 2x2:

0 1
1 1

我知道它与 offsetX/Y 值有关,这些变化取决于(小)矩阵的大小,我只是不知道计算这些结果的计算方法。我将把 offsetX/Y 传递给一个函数(带有向量),这样我就可以计算特定块的总和。

有人有建议吗?

谢谢

4

3 回答 3

4
import std.stdio : writeln;
void main(string[] args)
{
    int m=4, n=4;
    int[][] matrix = [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [1, 1, 0, 0]];
    int mm=2, nn=2;
    int sum;
    for(int x=0; x<m; x+=mm)
      for(int y=0; y<n; y+=nn)
        sum += summation(matrix, x, y, mm, nn);
    writeln(sum);
}    
int summation(int[][] matrix, int offsetx, int offsety, int m, int n)
{
  int sum;
  for(int x=offsetx; x<offsetx+m; x++)
    for(int y=offsety; y<offsety+n; y++)
      sum += matrix[x][y];
  return sum;
}

除非你在寻找别的东西?在解释您的要求时,您的问题含糊不清。

(这在 D 中编译,因为它是我唯一可以访问 atm 的东西,所以将它用作转换为 C++ 的指南)

于 2012-04-17T23:01:37.117 回答
3

为了在原位拆分矩阵(即不复制它),您需要一个可以同时处理原始和拆分部分的表示 - 这将使定义递归算法等变得更加容易:

template <class elt> class MatRef {
    elt* m_data;
    unsigned m_rows, m_cols;
    unsigned m_step;

    unsigned index(unsigned row, unsigned col)
    {
        assert(row < m_rows && col < m_cols);
        return m_step * row + col;
    }

public: // access
    elt& operator() (unsigned row, unsigned col)
    {
        return m_data[index(row,col)];
    }

public: // constructors
    MatRef(unsigned rows, unsigned cols, elt* backing)  // original matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(cols)
        , m_data(backing)
    {}
    MatRef(unsigned start_row, unsigned start_col,
           unsigned rows, unsigned cols, MatRef &orig) // sub-matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(orig.m_step)
        , m_data(orig.m_data + orig.index(start_row, start_col))
    {
        assert(start_row+rows <= orig.m_rows && start_col+cols <= orig.m_cols);
    }
};

原始矩阵构造函数假定它的backing参数指向一个至少rows*cols长的数据元素数组,用于存储矩阵数据。矩阵的维度由数据成员m_rows和定义m_cols

数据成员m_step表示从一行的开头到下一行的开头有多少个数据元素。对于原始矩阵,这与 相同m_cols。请注意,m_cols子矩阵的 可能小于它所指的原始矩阵的 —— 这就是子矩阵“跳过”原始矩阵中不属于子矩阵的元素的方式。为了使其正常工作,m_step必须与原始矩阵中的相同。

不管矩阵是否跳过元素,数据成员m_data总是指向矩阵的第一个元素。子矩阵构造函数中的assert()确保每个新的子矩阵都适合它所派生的矩阵。


我不确定这是否算作“有趣的算法”,但它是定义和访问子矩阵的一种有效且方便的方法。

于 2012-04-18T00:14:05.733 回答
1

从数学上讲,您可以使用曲线分割矩阵,例如 az 曲线或 peano 曲线。这样你也可以降低维度的复杂性。z 曲线使用 4 个四边形来分割一个平面,类似于四叉树。

编辑:我刚刚了解到它是 z 阶曲线而不是 z 曲线:http ://en.wikipedia.org/wiki/Z-order_curve 。z 曲线是生物信息学中的 3d http://en.wikipedia.org/wiki/Z_curve ??? 哈哈!我不是生物信息学家,也不是维基百科,但对我来说这听起来像是胡说八道。z 顺序曲线也可以覆盖 3d 区域。也许维基百科想说这个?这是一张 3d z 阶曲线的大图http://en.wikipedia.org/wiki/File:Lebesgue-3d-step3.png。它甚至在维基百科的文章中??????

于 2012-04-18T00:56:40.680 回答