2016-11-10 174 views
-2

1949年,數學家D. R. Kaprekar設計了一個現在稱爲Kaprekar操作的過程。首先選擇一個四位數字,其中的數字不完全相同(即不是1111,2222,...)。然後重新排列數字以獲得這些數字可以製作的最大和最小數字。最後,從最大的數中減去最小的數字以得到一個新的數字,然後對每個新的數字進行重複操作。Java中的神祕數字6174 [Kaprekar Theorem]

讓我們嘗試一下,從數字2005開始,最後一個 年份的數字。我們可以用這些數字作的最大數目是5200,和 最小值爲0025或25(如果一個或多個的位數是零時,嵌入 這些中的最小數目的左手側)

5200 - 0025 = 5175 
7551 - 1557 = 5994 
9954 - 4599 = 5355 
5553 - 3555 = 1998 
9981 - 1899 = 8082 
8820 - 0288 = 8532 
8532 - 2358 = 6174 

現在的目標是驗證這一定理&找到迭代次數採取達到6174

誰能給一個更好的算法?這是我的代碼。

public int VerifyKaprekarTheorem(int m) { 
    if (m <= 1000 || m > 9999) { 
     return -1; 
    } 
    String orginal = String.valueOf(m); 
    int count = 0; 
    while (true) { 
     int Max = Integer.parseInt(sortString(orginal, false)); 
     int Min = Integer.parseInt(sortString(orginal, true)); 
     count++; 
     int diff = Max - Min; 
     if (diff == 6174) { 
      break; 
     } 
     orginal = String.valueOf(diff); 
    } 
    return count; 
} 

public static String sortString(String Source, boolean assendingOrder) { 
    char[] original = String.valueOf(Source).toCharArray(); 
    Arrays.sort(original); 
    if (assendingOrder) { 
     return new String(original); 
    } 
    char[] dessending = new char[original.length]; 
    for (int i = original.length - 1; i >= 0; i--) { 
     dessending[i] = original[(original.length - 1) - i]; 
    } 
    return new String(dessending); 
} 

和測試用例

public void testCase01() { 
    int actual = VerifyKaprekarTheorem(4321); 
    assertEquals(3, actual); 
} 
+4

更適合codereview –

+3

沒有必要做整數字符串然後排序再次字符串整數。 – 2016-11-10 07:37:36

+0

@ScaryWombat以及像這樣的陳述_可以給任何人提供更好的算法嗎?_它也不適用於CR。 CR不是代碼_gimie。 – t3chb0t

回答

0

我有變化整數到字符串然後char數組不是再次排序整數轉換。

public int VerifyKaprekarTheorem(int m) { 
    if (m <= 1000 || m > 9999) { 
     return -1; 
    } 
    int count = 0; 
    while (true) { 
     int Max = largestNumber(m); 
     int Min = smallestNumber(m); 
     count++; 
     m = Max - Min; 
     if (m == 6174) { 
      break; 
     } 
    } 
    return count; 
} 
private static int largestNumber(int input) { 
    int[] numbers = new int[10]; 
    for (int i = input; i != 0; i /= 10) { 
     numbers[i % 10]++; 
    } 
    int counter = 0; 
    int result = 0; 
    for (int i = 0; i < 10; counter += numbers[i++]) { 
     result += (int) ((Math.pow(10, numbers[i]) * i - 1)/9) * Math.pow(10, counter); 
    } 
    return result; 
} 

private static int smallestNumber(int input) { 
    int[] numbers = new int[10]; 
    for (int i = input; i != 0; i /= 10) { 
     numbers[i % 10]++; 
    } 
    int counter = 0; 
    int result = 0; 
    for (int i = 9; i >= 0; counter += numbers[i--]) { 
     result += (int) ((Math.pow(10, numbers[i]) * i - 1)/9) * Math.pow(10, counter); 
    } 
    return result; 
} 
+0

有趣的你應該評論'不需要做整數字符串然後排序再次字符串整數'繼續呈現_exactly_那。最有趣的部分是方法名稱:「Kabuleke」背後的故事是什麼? – greybeard

+0

修改代碼!! – 2016-11-10 17:32:09

+0

未註釋爲代碼,我看到轉換爲十進制並返回二進制 - 一次小端,一次大端。我無法看到的是這是如何產生最小和最大的:請嘗試評論你的代碼,使密集可以看到。 – greybeard