下面是我被要求做的一个练习的实现(见评论)。它有效,我发布它的原因是函数 checkMiracle 看起来应该包含在一个更小的代码循环中 - 我正在写同样的东西加上十次。问题是,我似乎找不到更短的方法。我的问题是,有人可以向我指出减少此清单中代码的任何方向,也许需要考虑一些事情,使其更加紧凑或“聪明”的编码方式。任何帮助表示赞赏。 (练习表位于 JCF 上,所以他强迫我们使用集合进行编码)
/*A 10-digit decimal number N is said to be miraculous if it contains each of the ten decimal digits, and if
the 2-digit number consisting of the first two (most significant, i.e. leftmost) digits of N is divisible by
2, the 3-digit number consisting of the first three digits of N is divisible by 3, and so on up to and including
that N itself is divisible by 10. Write a program to discover a miraculous number (there really is one).
Proceed by making a list of the ten decimal digits, and repeatedly shuffling them until you chance upon an
arrangement that constitutes a miraculous number.
(Note: Type long rather than int is needed for 10-digit decimal integers.) */
import java.util.*;
public class Miracle {
static private long miracleNum = 0;
static private ArrayList<Integer> listing = new ArrayList<Integer>();
static String castValue = "";
public static void main(String[] args) {
for(int i = 0; i < 10; i++) listing.add(i);
Collections.shuffle(listing);
while(listing.get(0)==0) Collections.shuffle(listing); //make sure the number doesnt start with zero
while(!(checkMiracle(listing))) Collections.shuffle(listing);//keep changing it until we get a miracle number
for(long l : listing) castValue += l;
miracleNum = Long.parseLong(castValue);
System.out.println("Miracle num: " + miracleNum);
}
static public boolean checkMiracle(ArrayList<Integer> l) {
long checkValue = Long.parseLong("" + l.get(0) + l.get(1));
if(checkValue %2 != 0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2));
if(checkValue %3 != 0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3));
if(checkValue %4 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4));
if(checkValue %5 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4) + l.get(5));
if(checkValue %6 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4) + l.get(5) + l.get(6));
if(checkValue %7 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4) + l.get(5) + l.get(6) + l.get(7));
if(checkValue %8 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4) + l.get(5) + l.get(6) + l.get(7)+ l.get(8));
if(checkValue %9 !=0) return false;
checkValue = Long.parseLong("" + l.get(0) + l.get(1) + l.get(2) + l.get(3) + l.get(4) + l.get(5) + l.get(6) + l.get(7)+ l.get(8) + l.get(9));
if(checkValue %10 !=0) return false;
return true;
}
}
为什么不在循环中收集所有条件?然后您只需将下一位数字添加到数字即可计算下一个。
String partial = Long.parseLong(l.get(0));
for (int i = 1; i < 10; ++i) {
partial += Long.parseLong(l.get(i));
if (Long.valueOf(partial) % (i+1) != 0)
return false;
}
return true;
此外,您可以通过使用求幂来避免使用字符串
digit^(displacement)
。必须通过使用集合来解决类似的问题似乎很奇怪..
也许可以使用循环删除一些重复的代码:
private static boolean checkMiracleN(List<Integer> l, int n){
long sum = 0;
for (int i=0; i<n; i++)
sum = sum * 10 + l.get(i);
return sum % n == 0;
}
private static boolean checkMiracle(ArrayList<Integer> l){
for (int n=2; n<=10; n++)
if (!checkMiracleN(l, n)
return false;
return true;
}
使用辅助函数,以便您可以用循环替换重复的代码:
static public String GetNumberString(ArrayList<Integer> l, int numDigits)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < numDigits; i++)
{
sb.Append(l.get(i));
}
return sb.ToString();
}
static public boolean checkMiracle(ArrayList<Integer> l) {
long checkValue = 0;
for (int i = 2; i < 10; i++)
{
checkValue = Long.parseLong(GetNumberString(l, i));
if(checkValue % i != 0) return false;
}
}
这仍然意味着您每次都会构建非常相似的字符串。 一种改进是在每次循环迭代中增量构建数字,而不是每次都重建它。
您可以采取一些捷径。 例如如果一个数字是偶数,那么它的最后一位数字必须是偶数
if (l.get(1) % 2 == 0) 返回 false;
如果一个数字是十的倍数,它的最后一位数字必须是“0”
if (l.get(9) == 0) 返回 false;
如果一个数字是 3 的倍数,则其数字是 3 的倍数的和(9 也一样)
如果数字是 5 的倍数,则最后一位数字必须是 5 或 0。
在大多数情况下,您不需要 * 或 %。 你绝对不需要创建一个字符串并解析它。
public static String isPossible(long n, long 1, long s) {
长和 1*(1+1)/2;
长开始 = 1;
长端 = 1;
长 currSum = 总和;
if (currSum == s)
返回“是”;
同时(结束< n) {
currSum = currSum 开始 + 结束 + 1;
if (currSum == s || (currSum end == s)) { return "YES";
}
开始++;
结束++;
我
}
返回“否”;
}