漢諾塔計數 實現輸出64個圓盤移動多少次 java程式碼
阿新 • • 發佈:2019-02-18
因為漢羅塔的個數如果為1,2,3,4;那麼對應的移動次數為1,3,7,15相當於2^n-1,也可以說是上一次的結果乘以2加上1就是下一次的結果
由於當漢羅塔多了之後後面的數字會很大,有可能java的型別無法支援如此大的數,也為了可以快速高效的計算出結果,此時就不能用一般的方法統計,這裡我採用的是通過陣列的方式實現疊加統計
例如:a[] = {0,0,1,4}表示4位數,結果是14 如果要當其中某一位出現大於10的就向前一位進1,例如{0,2,23,11,3}得出的結果實際上應該是{0,4,4,1,3}:4413
如果這個數需要乘以一個數那麼就和每一位上的相乘最後進位,例如:{0,6,2}*2={0,12,4}={1,2,4}=124這樣的道理
最後用一個字串來得出最後的結果數字就可以了
下面的程式a[]表示用於統計的結果,是一個字串陣列,b[]表示上一個的結果陣列,c[]表示乘以2減去1後的結果陣列
最後結果:總共64個圓盤共移動了:18446744073709551615次
由於當漢羅塔多了之後後面的數字會很大,有可能java的型別無法支援如此大的數,也為了可以快速高效的計算出結果,此時就不能用一般的方法統計,這裡我採用的是通過陣列的方式實現疊加統計
例如:a[] = {0,0,1,4}表示4位數,結果是14 如果要當其中某一位出現大於10的就向前一位進1,例如{0,2,23,11,3}得出的結果實際上應該是{0,4,4,1,3}:4413
如果這個數需要乘以一個數那麼就和每一位上的相乘最後進位,例如:{0,6,2}*2={0,12,4}={1,2,4}=124這樣的道理
最後用一個字串來得出最後的結果數字就可以了
下面的程式a[]表示用於統計的結果,是一個字串陣列,b[]表示上一個的結果陣列,c[]表示乘以2減去1後的結果陣列
public class 漢羅塔計數 { // N為多少個圓盤 public static int N = 64;//這裡可以自己修改 /** * 處理結果 * @param a 得到的每一次運算的結果陣列 * @param c 得到當前移動的次數的陣列(也就是上一次的結果) * @param n 遞迴次數的變數 */ public static void processResult(String a[], int c[], int n) { //首先判斷遞迴次數是否小於制定的漢羅塔的個數-1(n從0開始的) if (n < N - 1) { for (int i = 0; i < N; i++) { if (c[i] == 0) {//如果前面為0表示不是第一位:例如0014=14,不需要0 continue; } else { //取出這個數字放入a中 for (int j = i; j < N; j++) { a[n + 1] += String.valueOf(c[j]); } break; } } //如果是最後一次計數,則輸出結果,直接結束方法 if (n == a.length - 2) { System.out.println("總共" + N + "個圓盤共移動了:" + a[n + 1] + "次"); return; } //繼續遞迴 processResult(a, getLastResult(a, c, n + 1), n + 1); } } /** * 獲取上一個結果 * @param a * @param c * @param n * @return */ public static int[] getLastResult(String a[], int c[], int n) { //b用於獲取上一次的結果 int b[] = new int[N]; //先把字串轉變為一個個字元然後放入陣列中 char[] t = a[n].toCharArray(); for (int i = 0; i < t.length; i++) { b[t.length - 1 - i] = t[i] - '0'; } //每個數字乘以2再放入c[]中 for (int i = 0; i < t.length; i++) { c[N - 1 - i] = b[i] * 2; } c[N - 1]++;//加1 //進行進位處理 for (int i = N - 1; i > 0; i--) { if (c[i] >= 10) { c[i - 1] += c[i] / 10; c[i] %= 10; } } return c; } public static void main(String[] args) { //初始化a String a[] = new String[N]; if (N == 1) { System.out.println("總共1個圓盤共移動了:1次"); } else { for (int i = 0; i < a.length; i++) { a[i] = ""; } int c[] = new int[N]; a[0] = "1";//如果不是一個圓盤,那麼a[0]的結果是1 //開始處理結果 processResult(a, getLastResult(a, c, 0), 0); } } }
最後結果:總共64個圓盤共移動了:18446744073709551615次