2016-11-10 10 views
-2

1949年に数学者D. R. Kaprekarは、現在カプリカの操作として知られているプロセスを考案しました。最初に、数字がすべて同じでない4桁の数字を選択します(1111、2222、...ではありません)。次に、数字を並べ替えると、これらの数字でできる最大値と最小値が得られます。最後に、最大から最小の番号を減算して新しい番号を取得し、新しい番号ごとに操作を繰り返す。神秘的な数6174 [Kaprekar定理] Javaで

2005年の数字から始まって、最後に 年の数字を試してみましょう。我々はこれらの数字を用いて作ることができる最大数は5200であり、そして(数字の1つ以上がゼロである場合に最小数の左側に これらを埋め込む) 最小値は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

整数を文字列に並べ替え、次に整数を並べ替える必要はありません。 –

+0

@ScaryWombatこのようなステートメントで、うまくいけばいいのですが、誰かがより良いアルゴリズムを与えることができますか?それはCRにも適していません。 CRは虚偽のコードではありません。 – t3chb0t

答えて

0

Iは、変更[文字列の整数再び整数変換を並べ替えよりチャーアレイを有しています。

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

おかげで、あなたは '正確に文字列を並べ替える必要はありませんし、もう一度文字列を並べ替える必要はありません。最も興味深い部分はメソッド名です:「カブレケ」の背後にある物語は何ですか? – greybeard

+0

変更されたコード! –

+0

コードのコメントがついていないので、10進数への変換と2進数への変換を参照してください - 一度リトルエンディアン、一度ビッグエンディアン。私が見ることができないのは、これがどのようにして最小かつ最大のものになるかです。密なものが見えるようにコードにコメントしてみてください。 – greybeard