Java 集合逻辑/过度编码问题
下面是我被要求做的一个练习的实现(见评论)。它有效,我发布它的原因是函数 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;
}
}
Below is an implementation of an exercise I've been asked to do (see comments). It works, and the reason I'm posting it is that the function checkMiracle looks like it should be contained in a much smaller loop of code - I'm writing out the same thing plus one ten times. The problem is, I can't seem to find a shorter way of doing it. My question then is can someone point me in any direction of reducing the code in this listing, maybe something to think about that makes it more compact or a 'clever' way of coding it. Any help appreciated. (The exercise sheet is on the JCF so he is forcing us to code this using collections)
/*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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么不在循环中收集所有条件?然后您只需将下一位数字添加到数字即可计算下一个。
此外,您可以通过使用指数
digit^(displacement)
来避免使用字符串。必须通过使用集合来解决类似的问题似乎很奇怪。why don't you gather all the conditions inside a loop? Then you can just add next digit to the number to calculate next one.
in addition you could avoid using strings by using exponentiation
digit^(displacement)
. Having to solve a similar problem by using collections seems groesque..也许使用循环删除一些重复的代码:
Maybe remove some code duplication using loops:
使用辅助函数,以便您可以用循环替换重复的代码:
这仍然意味着您每次都会构建非常相似的字符串。一种改进是在每次循环迭代时增量地构建数字,而不是每次都重建它。
Use a helper function so that you can replace repeated code with a loop:
This still means that you're building a very similar string each time. An improvement would be to incrementally build the number on each loop iteration, instead of rebuilding it each time.
您可以采取一些捷径。
例如,如果一个数字是偶数,那么它的最后一位数字必须是偶数
if (l.get(1) % 2 == 0) return false;
如果一个数字是十的倍数,则其最后一位数字必须是“0”
if (l.get(9) == 0) return false;
如果一个数字是 3 的倍数,则其数字是 3 的倍数的和(与 9 相同)
如果一个数字是 5 的倍数,则其最后一位数字必须是 5 或 0。
在大多数情况下,您不需要到 * 或 %。您绝对不需要创建字符串并解析它。
A couple of short cuts you can make.
e.g. if a number is even its last digit must be even
if (l.get(1) % 2 == 0) return false;
if a number is a multiple of ten, its last digit must be a '0'
if (l.get(9) == 0) return false;
If a number is a multiple if 3, the sum if its digits are multiple of three (same for 9)
If a number is a multiple of 5, its last digit must be a 5 or 0.
In most cases you don't need to * or a %. You definitley don't need to create a String and parse it.