前天我看線代書,看到行列式,發現是個遞歸的式子,恰巧又正在學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; } } }
