Java集合逻辑/过度编码问题
下面是我被要求做的一个练习的实现,请看评论。它是有效的,我之所以发布它,是因为函数checkMiracle看起来应该包含在一个更小的代码循环中——我写了同样的东西加上十次。问题是,我似乎找不到比这更短的方法了。那么,我的问题是,有没有人能告诉我如何减少清单中的代码,也许可以考虑一些让它更紧凑的方法,或者是一种“聪明”的编码方法。谢谢你的帮助。练习表在JCF上,所以他强迫我们使用集合来编写Java集合逻辑/过度编码问题,java,collections,logic,Java,Collections,Logic,下面是我被要求做的一个练习的实现,请看评论。它是有效的,我之所以发布它,是因为函数checkMiracle看起来应该包含在一个更小的代码循环中——我写了同样的东西加上十次。问题是,我似乎找不到比这更短的方法了。那么,我的问题是,有没有人能告诉我如何减少清单中的代码,也许可以考虑一些让它更紧凑的方法,或者是一种“聪明”的编码方法。谢谢你的帮助。练习表在JCF上,所以他强迫我们使用集合来编写 /*A 10-digit decimal number N is said to be miraculous
/*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;
}
}
可能会使用循环删除一些代码重复:
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;
}
可能会使用循环删除一些代码重复:
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;
}
为什么不在一个循环中收集所有条件?然后你可以把下一个数字加到数字上,计算下一个数字
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;
此外,可以通过使用求幂数字^displacement避免使用字符串。必须通过使用集合来解决类似的问题似乎很糟糕。为什么不在一个循环中收集所有条件?然后你可以把下一个数字加到数字上,计算下一个数字
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;
此外,可以通过使用求幂数字^displacement避免使用字符串。必须通过使用集合来解决类似的问题似乎很糟糕。使用辅助函数,以便可以用循环替换重复的代码:
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;
}
}
这仍然意味着您每次都在构建一个非常相似的字符串。一种改进是,在每次循环迭代中递增地生成编号,而不是每次都重新生成编号。使用辅助函数,以便可以用循环替换重复的代码:
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;
}
}
这仍然意味着您每次都在构建一个非常相似的字符串。一个改进是在每次循环迭代中递增地构建编号,而不是每次都重新构建编号。您可以走几条捷径。 e、 g.如果一个数字是偶数,则其最后一个数字必须是偶数 如果l.get1%2==0,则返回false 如果数字是十的倍数,则其最后一位数字必须是“0” 如果l.get9==0,则返回false 如果一个数字是3的倍数,那么如果它的数字是3的倍数,那么和等于9 如果数字是5的倍数,则其最后一位数字必须是5或0
在大多数情况下,你不需要*或%。您无需创建字符串并对其进行解析。您可以走几条捷径。 e、 g.如果一个数字是偶数,则其最后一个数字必须是偶数 如果l.get1%2==0,则返回false 如果数字是十的倍数,则其最后一位数字必须是“0” 如果l.get9==0,则返回false 如果一个数字是3的倍数,那么如果它的数字是3的倍数,那么和等于9 如果数字是5的倍数,则其最后一位数字必须是5或0
在大多数情况下,你不需要*或%。您无需创建字符串并对其进行解析。+1是唯一一个重复使用分部结果以避免嵌套循环的答案。分部可以生成一个long,而无需在每一步都使用partial=partial*10+l.geti的求幂运算。这不会编译字符串partial=long。。。当我把它改为what do compile时,逻辑就关闭了,给出了错误的答案。很容易检查,任何不是38165472920的答案都是错误的。我无法解决你的问题。我试图实现一个想法,你应该通过理解概念解决方案,而不是书面解决方案,自己解决这个问题。我们不是来做你的工作的,只是来帮忙的:所以不要抱怨……无论如何,我建议的方法是绝对正确的。但我不想浪费时间来适应字符串和集合的使用,而不是简单的数字。这是你的职责。+1是唯一一个重复使用分部结果以避免嵌套循环的答案。分部可以被做成一个long,而无需在每一步都使用partial=partial*10+l.geti的求幂运算。这不会编译字符串partial=long。。。当我把它改为what do compile时,逻辑就关闭了,给出了错误的答案。很容易检查,任何不是38165472920的答案都是错误的。我无法解决你的问题。我试图实现一个想法,你应该通过理解概念解决方案,而不是书面解决方案,自己解决这个问题。我们不是来做你的工作的,只是来帮忙的:所以不要抱怨……无论如何,我建议的方法是绝对正确的。但我不想浪费时间来适应字符串和集合的使用,而不是简单的数字。这是你的职责。这真的很酷,不起作用。不幸的是,我认为它被1除掉了,它给出的答案不能被10除掉,它在某一点上给了我3816547209。我会看看我是否能让它工作。这个想法是向你展示如何重构你的代码以消除重复,而不是提供保证完全没有bug的代码:-这真的很酷,不起作用,不幸的是,我认为它差一点,不是吗
他给出的答案不能被10整除,它在某一点上给了我3816547209。我会看看我是否能让它工作。这个想法是告诉你如何重构你的代码以消除重复,而不是提供保证完全没有bug的代码:-算法上最好的是计算2*3*5*7 210,找到可以除以210的前10位数字,然后依次搜索幻数,通过检查第一个数字,加上210,然后检查结果等等…从算法上来说,最好是计算2*3*5*7 210,找到可被210除的前10位数字,然后依次搜索幻数,方法是检查第一位数字、添加210并检查结果等等。。。