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

发布于 2024-09-28 13:44:38 字数 2968 浏览 4 评论 0原文

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

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

非要怀念 2024-10-05 13:44:38

为什么不在循环中收集所有条件?然后您只需将下一位数字添加到数字即可计算下一个。

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) 来避免使用字符串。必须通过使用集合来解决类似的问题似乎很奇怪。

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.

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;

in addition you could avoid using strings by using exponentiation digit^(displacement). Having to solve a similar problem by using collections seems groesque..

偏爱自由 2024-10-05 13:44:38

也许使用循环删除一些重复的代码:

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

Maybe remove some code duplication using loops:

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;
}
我不咬妳我踢妳 2024-10-05 13:44:38

使用辅助函数,以便您可以用循环替换重复的代码:

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

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

Use a helper function so that you can replace repeated code with a loop:

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

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.

一梦浮鱼 2024-10-05 13:44:38

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

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.

初吻给了烟 2024-10-05 13:44:38
public static String isPossible(long n, long 1, long s) {
  long sum 1*(1+1)/2;
  long start = 1;
  long end = 1;
  long currSum = sum;

  if (currSum == s)
    return "YES";

  while (end < n) 
  {
    currSum = currSum start + end + 1;
    if (currSum == s || (currSum end == s)) 
      { 
        return "YES";
      }

    start++;
    end++;
  }

return "NO";

}
public static String isPossible(long n, long 1, long s) {
  long sum 1*(1+1)/2;
  long start = 1;
  long end = 1;
  long currSum = sum;

  if (currSum == s)
    return "YES";

  while (end < n) 
  {
    currSum = currSum start + end + 1;
    if (currSum == s || (currSum end == s)) 
      { 
        return "YES";
      }

    start++;
    end++;
  }

return "NO";

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文