Java中的神秘数字6174[卡普雷卡定理]
1949年,数学家D.R.Kaprekar设计了一个现在称为Kaprekar运算的过程。首先选择一个四位数的数字,其中数字不完全相同(即不是1111、2222、…)。然后重新排列这些数字,以获得这些数字可以生成的最大和最小数字。最后,从最大的数中减去最小的数字,以获得新的数字,并对每个新数字重复该操作 让我们试一下,从数字2005开始,最后的数字 一年。我们能用这些数字做的最大数字是5200,并且 最小值为0025或25(如果一个或多个数字为零,则嵌入 这些在最小数量的左侧) 现在的目标是验证这个定理&找到达到6174的迭代次数 有人能给出更好的算法吗?这是我的代码Java中的神秘数字6174[卡普雷卡定理],java,algorithm,math,Java,Algorithm,Math,1949年,数学家D.R.Kaprekar设计了一个现在称为Kaprekar运算的过程。首先选择一个四位数的数字,其中数字不完全相同(即不是1111、2222、…)。然后重新排列这些数字,以获得这些数字可以生成的最大和最小数字。最后,从最大的数中减去最小的数字,以获得新的数字,并对每个新数字重复该操作 让我们试一下,从数字2005开始,最后的数字 一年。我们能用这些数字做的最大数字是5200,并且 最小值为0025或25(如果一个或多个数字为零,则嵌入 这些在最小数量的左侧) 现在的目标是验证这
我将整数改为字符串,然后再将字符数组排序,然后再进行整数转换
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;
}