前天我看线代书,看到行列式,发现是个递归的式子,恰巧又正在学java,产生写程序实现的想法。写了两个小时,觉得实现了,写了个行列式放进去测试,我放的是
1 2 3 4 5 6 7 8 9
这个行列式,经过程序计算后发现结果是0。我以为我错了,于是我就去找错,发现返回结果的变量好像应该用静态变量,否则可能面临每次调用都初始化为0的情况,我以为这是结果是0的原因 。于是,我把结果变量改为静态变量,得到的结果不是0了,甚是高兴。于是用计算器验证我放进去的1-9的那个行列式的结果,发现竟然是0。 此时,我没有意识到我原本写的是对的,以为我这次是函数的结构或者其他啥的问题。几经折腾,发现改完之后只能计算二阶行列式能得到正确结果,三阶就不正确。再几经思考,发现在递归调用过程中,把结果储存到静态变量里时会进行重复的加,递归内加了一次,递归完成后又加了一次。遂改回原来的,得正确结果 。全程历时四小时有余,两小时写完代码,再两小时把代码改错且难受的思考再把代码改回原样。
从这个故事我学会一件事,0不一定是错误结果
下面是我写的代码。
public class recursive { public static void main(String[] args) { // 定义一个数组 int a[][] = {{1,2},{2,1}}; aij b = new aij(); System.out.println(b.det(a)); } } class aij { // A函数可用于求余子阵 int[][] A(int[][] a, int row, int column) { int[][] ans = new int[a.length - 1][a.length - 1];// ans用于储存返回的最终结果 int[] temp = new int[(a.length - 1) * (a.length - 1)];// 临时一维数组temp用于按顺序储存剔除相应行和列元素后的数组 int k = 0; // 剔除行和列并按顺序储存到temp内 for (int i = 0; i < a.length; i++) { for (int j = 0; j < a[i].length; j++) { if (i == row - 1) { continue; } else if (j == column - 1) { continue; } temp[k++] = a[i][j]; } } // 按顺序从temp中读取数据并储存到ans内 k = 0; for (int i = 0; i < ans.length; i++) { for (int j = 0; j < ans[i].length; j++) { ans[i][j] = temp[k++]; } } return ans; } // det用于求行列式 int det(int[][] a) { if (a.length == 1) { return a[0][0]; } else { int ans=0; for (int i = 0; i < a.length; i++) { ans+=a[i][0]*(int)Math.pow(-1, i)*det(A(a,i+1,1)); } return ans; } } }