以下是我被要求做的练习的实施(见评论)。它的工作原理,我发布它的原因是函数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;
}
}
答案 0 :(得分:3)
为什么不收集循环内的所有条件?然后你可以在数字上添加下一个数字来计算下一个数字。
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)
来避免使用字符串。必须通过使用集合解决类似的问题似乎是groesque ..
答案 1 :(得分:2)
也许使用循环删除一些代码重复:
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;
}
答案 2 :(得分:1)
使用辅助函数,以便您可以用循环替换重复的代码:
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;
}
}
这仍然意味着您每次都要构建一个非常相似的字符串。一个改进是在每次循环迭代中逐步建立数字,而不是每次都重建它。
答案 3 :(得分:0)
你可以做几个捷径。 例如如果数字是偶数,那么它的最后一位数字必须是偶数
if(l.get(1)%2 == 0)返回false;
如果数字是十的倍数,则其最后一位必须为“0”
if(l.get(9)== 0)返回false;
如果数字是3的倍数,则数字的总和是3的倍数(9相同)
如果数字是5的倍数,则其最后一位必须是5或0。
在大多数情况下,您不需要*或%。你definitley不需要创建一个String并解析它。