Java 集合逻辑/过度编码问题

问题描述 投票:0回答:5

下面是我被要求做的一个练习的实现(见评论)。它有效,我发布它的原因是函数 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;


 }


}
java collections logic
5个回答
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)
。必须通过使用集合来解决类似的问题似乎很奇怪..


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;
}

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;
  }
}

这仍然意味着您每次都会构建非常相似的字符串。 一种改进是在每次循环迭代中增量构建数字,而不是每次都重建它。


0
投票

您可以采取一些捷径。 例如如果一个数字是偶数,那么它的最后一位数字必须是偶数

if (l.get(1) % 2 == 0) 返回 false;

如果一个数字是十的倍数,它的最后一位数字必须是“0”

if (l.get(9) == 0) 返回 false;

如果一个数字是 3 的倍数,则其数字是 3 的倍数的和(9 也一样)

如果数字是 5 的倍数,则最后一位数字必须是 5 或 0。

在大多数情况下,您不需要 * 或 %。 你绝对不需要创建一个字符串并解析它。


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";

}

开始++;

结束++;

}

返回“否”;

}

© www.soinside.com 2019 - 2024. All rights reserved.