我正在尝试提出以下问题的非暴力解决方案。给定任意大小的矩阵:
[6 0 3 5]
[3 7 1 4]
[1 4 8 2]
[0 2 5 9]
将其对角线转换为向量列表,如下所示:
(0)
(1, 2)
(3, 4, 5)
(6, 7, 8, 9)
(0, 1, 2)
(3, 4)
(5)
在这个例子中,从左下到右上工作,有没有一种优雅的方法来完成这个任务,而不是迭代左列和上行?
(未经检查的代码) 类似这样(Java 代码):
// suppose m is the matrix, so basically an int[][] array with r rows and c columns
// m is an int[rows][cols];
List result = new ArrayList(rows + cols - 1);
for (int i = 0; i < (rows + cols - 1))
{
int y;
int x;
if (i < rows)
{
x = 0;
y = rows - i - 1;
}
else
{
x = i - rows + 1;
y = 0;
}
Vector v = new Vector();
while (y < rows && x < cols)
{
y++;
x++;
v.add(new Integer(m[y][c]));
}
result.add(v);
}
// result now contains the vectors you wanted
编辑:我把x和y搞混了,现在已经更正。
Mathematica:
m = {{6, 0, 3, 5},
{3, 7, 1, 4},
{1, 4, 8, 2},
{0, 2, 5, 9}};
Table[Diagonal[m, i], {i, 1 - Length@m, Length@m[[1]] - 1}]
该函数返回第i条对角线的列表,其中第0条对角线是主对角线,i = -1表示它下面的一条对角线,以此类推。
{{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}, {0, 1, 2}, {3, 4}, {5}}
当然,使用内置的Diagonal
函数有点作弊。这里是一个从头开始实现Diagonal
的方法:
(* Grab the diagonal starting from element (i,j). *)
diag0[m_,i_,j_] := Table[m[[i+k, j+k]], {k, 0, Min[Length[m]-i, Length@m[[1]]-j]}]
(* The i'th diagonal -- negative means below the main diagonal, positive above. *)
Diagonal[m_, i_] := If[i < 0, diag0[m, 1-i, 1], diag0[m, 1, i+1]]
Table
函数基本上是一个for循环,它会将结果收集到一个列表中。例如:
Table[2*i, {i, 1, 5}]
返回{2,4,6,8,10}
。