一,问题描述
所谓“数字黑洞”现象,就是任意给定一个4位正整数,将组成该正整数的4个数字先按非递减顺序排序,得到一个数称为Large;再将这4个数字按非递增顺序排序,得到另一个数,称为Small。然后,将Large减去Small,得到一个新的数字。当然,其它位数的也存在着这个现象,具体可参考:数字黑洞
将这个新的数字重复上面的处理,很快就会停在有“数字黑洞”之称的 6174 这个数上。这个数也称为Kaprekar常数。
二,举例说明
比如,输入6767,其演示结果如下:
7766 - 6677 = 1089
9810 - 0189 = 9621 ----将新得到的数 1089 进行非递减及 非递增排序后,分别得到 9810 和 0189(189)
9621 - 1269 = 8352
8532 - 2358 = 6174
三,核心思路分析
这个问题的核心过程是:将数字分解成各个位,然后按非递增或非递减排序,再得到排序后的数字。
数字分解的话,可以用求余 和 除法。排序的话,可以用Arrays.sort(int[] arr)。得到排序后的数字,其实就是Horner法则。
①数字分解:
privatestatic int[] split(intn){
//assert n >= 1000; assert n <= 9999int[] arr = new int[4];int index = 0;while(n != 0)
{
arr[index++] = n % 10;
n= n / 10;
}returnarr;
}
②Horner法则得到数字:关于Horner法则可参考:求幂运算、多项式乘法及Horner法则的应用
//1089-->9810, arr是从小到大的有序数组
privatestatic int toLarge(int[] arr){int result = 0;for(int i = arr.length - 1; i >=0; i--)
{
result= result*10 +arr[i];
}returnresult;
}//1089 --> 189arr是从小到大的有序数组
privatestatic int toSmall(int[] arr){int result = 0;for(int i = 0; i < arr.length; i++)
{
result= result*10 +arr[i];
}returnresult;
}
四,整个代码完整实现:
importjava.util.Arrays;importjava.util.Scanner;public classMain {public static voidmain(String[] args) {
Scanner in= newScanner(System.in);while (in.hasNextInt()) {//注意while处理多个case
int number =in.nextInt();int[] arr =split(number);if(check(arr))
{
System.out.println(number+ " - " + number + " = " + "0000");
}else{int res =process(number);while(res != 6174)
{
res=process(res);
}
}
}
}public static int[] split(intn){int[] arr = new int[4];int index = 0;while(n != 0)
{
arr[index++] = n % 10;
n= n / 10;
}returnarr;
}public static void sort(int[] arr){
Arrays.sort(arr);
}public static int toLarge(int[] arr){int result = 0;for(int i = arr.length - 1; i >=0; i--)
{
result= result*10 +arr[i];
}returnresult;
}public static int toSmall(int[] arr){int result = 0;for(int i = 0; i < arr.length; i++)
{
result= result*10 +arr[i];
}returnresult;
}public static int process(intn){int[] arr =split(n);
Arrays.sort(arr);int large =toLarge(arr);int small =toSmall(arr);
print(large, small, arr);return large -small;
}public static void print(int large, int small, int[] arr){
System.out.println(large+ " - " + arr[0] + arr[1] + arr[2] + arr[3] + " = " + (large -small));
}public static boolean check(int[] arr){int tmp = arr[0];for(int i = 1; i < arr.length; i++)if(arr[i] !=tmp)return false;return true;
}
}
View Code