我已经从上一个问题中得到了提示,并深入调试我的代码。我仍然试图制作一个方法,它采用两个多维数组n * n并将它们相乘,就好像它们是矩阵一样。但我遇到了一个奇怪的障碍。这是我的代码:
public class subMatrix {
public int[][] divcon(int[][] a, int[][] b, int sub) {
int[][] matrixC = new int[a.length][a.length];
if (sub == 1) {
matrixC[0][0] = a[0][0] * b[0][0];
} else {
sub = sub / 2;
int[][] smalla11 = new int[sub][sub];
int[][] smalla12 = new int[sub][sub];
int[][] smalla21 = new int[sub][sub];
int[][] smalla22 = new int[sub][sub];
int[][] smallb11 = new int[sub][sub];
int[][] smallb12 = new int[sub][sub];
int[][] smallb21 = new int[sub][sub];
int[][] smallb22 = new int[sub][sub];
int[][] smallc11 = new int[sub][sub];
int[][] smallc12 = new int[sub][sub];
int[][] smallc21 = new int[sub][sub];
int[][] smallc22 = new int[sub][sub];
for (int i = 0; i < sub; i++) {
for (int j = 0; j < sub; j++) {
smalla11[i][j] = a[i][j];
smalla12[i][j] = a[sub + i][j];
smalla21[i][j] = a[i][sub + j];
smalla22[i][j] = a[sub + i][sub + j];
smallb11[i][j] = b[i][j];
smallb12[i][j] = b[sub + i][j];
smallb21[i][j] = b[i][sub + j];
smallb22[i][j] = b[sub + i][sub + j];
}
}
smallc11 = addMatrix(divcon(smalla11, smallb11, sub), divcon(smalla12, smallb21, sub), sub);
smallc12 = addMatrix(divcon(smalla11, smallb12, sub), divcon(smalla12, smallb12, sub), sub);
smallc21 = addMatrix(divcon(smalla21, smallb11, sub), divcon(smalla22, smallb21, sub), sub);
smallc22 = addMatrix(divcon(smalla21, smallb12, sub), divcon(smalla22, smallb22, sub), sub);
}
return matrixC;
}
public int[][] addMatrix(int[][] aadd, int[][] badd, int size) {
int[][] c = new int[size][size];
for (int d = 0; d < size; d++) {
for (int e = 0; e < size; e++) {
c[d][e] = aadd[d][e] + badd[d][e];
}
}
return c;
}
}
矩阵a和b变成了四分之一。我用两个matrice输入4x4调试了我的代码,每个字段的值为2。直到某一点,事情才是正确的。但是,如果我添加System.out.println()
来查看smallc11
,12,21和22的返回值,它有时会显示为0.为什么?我永远不会输入任何0,并且数组的长度不应低于1,即2。
答案 0 :(得分:0)
您正在返回matrixC
,但您并未在任何地方更改它,因此它将会充满0
。
您可以复制所有子矩阵的结果,但更简单的事情不是首先创建它们。只需将两个原始矩阵的所有元素加在一起就会更简单,更快捷。
像
这样的东西public double[][] multiply(double[][] a, double[][] b) {
assert a[0].length == b.length;
double[][]c = new double[a.length][b[0].length];
for(int i = 0, len1 = a.length; i < len1; a++) {
for(int j = 0, len2 = b[0].length; j < len2; j++) {
double sum = 0.0;
for(int k = 0, len3 = b.length; k < len3; k++)
sum += a[i][k] * b[k][j];
c[i][j] = sum;
}
}
}
更快的原因是创建新对象和复制值的成本超过了*
和+
的成本。
您可以先通过转置b
来进一步优化,以提高缓存友好性。