Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的神秘数字6174[卡普雷卡定理]_Java_Algorithm_Math - Fatal编程技术网

Java中的神秘数字6174[卡普雷卡定理]

Java中的神秘数字6174[卡普雷卡定理],java,algorithm,math,Java,Algorithm,Math,1949年,数学家D.R.Kaprekar设计了一个现在称为Kaprekar运算的过程。首先选择一个四位数的数字,其中数字不完全相同(即不是1111、2222、…)。然后重新排列这些数字,以获得这些数字可以生成的最大和最小数字。最后,从最大的数中减去最小的数字,以获得新的数字,并对每个新数字重复该操作 让我们试一下,从数字2005开始,最后的数字 一年。我们能用这些数字做的最大数字是5200,并且 最小值为0025或25(如果一个或多个数字为零,则嵌入 这些在最小数量的左侧) 现在的目标是验证这

1949年,数学家D.R.Kaprekar设计了一个现在称为Kaprekar运算的过程。首先选择一个四位数的数字,其中数字不完全相同(即不是1111、2222、…)。然后重新排列这些数字,以获得这些数字可以生成的最大和最小数字。最后,从最大的数中减去最小的数字,以获得新的数字,并对每个新数字重复该操作

让我们试一下,从数字2005开始,最后的数字 一年。我们能用这些数字做的最大数字是5200,并且 最小值为0025或25(如果一个或多个数字为零,则嵌入 这些在最小数量的左侧)

现在的目标是验证这个定理&找到达到6174的迭代次数

有人能给出更好的算法吗?这是我的代码


我将整数改为字符串,然后再将字符数组排序,然后再进行整数转换

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;
}
public int-verifykaprekar定理(int-m){
如果(m 9999){
返回-1;
}
整数计数=0;
while(true){
int Max=最大数量(m);
int Min=最小数(m);
计数++;
m=最大-最小值;
如果(m==6174){
打破
}
}
返回计数;
}
私有静态最大整数(整数输入){
整数[]个数=新整数[10];
对于(int i=输入;i!=0;i/=10){
数字[i%10]++;
}
int计数器=0;
int结果=0;
对于(int i=0;i<10;计数器+=数字[i++]){
结果+=(int)((数学功率(10,数字[i])*i-1)/9)*数学功率(10,计数器);
}
返回结果;
}
私有静态int smallestNumber(int输入){
整数[]个数=新整数[10];
对于(int i=输入;i!=0;i/=10){
数字[i%10]++;
}
int计数器=0;
int结果=0;
对于(int i=9;i>=0;计数器+=数字[i--]){
结果+=(int)((数学功率(10,数字[i])*i-1)/9)*数学功率(10,计数器);
}
返回结果;
}

更适合CodeReview无需对字符串进行整数排序,然后再对字符串进行整数排序。@ScaryWombat好吧,有这样一句话,有人能给出更好的算法吗?它也不适合CR。CR不是gimie teh代码。@t3chb0t取点。您所说的更好的算法是什么意思?时间/空间复杂性、代码大小、优化?你可以去掉字符串,添加备忘录等等。。。我在C++中的尝试在我的安装上使用了0.55毫秒(整个4位数范围,不仅仅是粗略的单个数字)…在不知道您想要改进什么的情况下很难回答有趣的是,您应该注释
不需要进行整数到字符串的排序,然后再次进行字符串到整数的排序
,以继续准确地呈现。最有趣的部分是方法名:
Kabuleke
?修改后的代码!!虽然代码没有注释,但我看到了十进制和二进制的转换——一次是小端,一次是大端。我看不出这是如何生成最小和最大的代码的:请尝试注释您的代码,以便代码管理员可以看到。
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);
}
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;
}