项目Euler#3 Java解决方案问题

时间:2009-11-01 02:16:38

标签: java debugging

class eulerThree {

    public static void main(String[] args) {

        double x = 600851475143d; 

        for (double z = 2; z*z <= x; z++) {

            if (x%z == 0) {

                System.out.println(z + "PRIME FACTOR");

            }

        }

    }

}

,输出为:

71.0
839.0
1471.0
6857.0
59569.0
104441.0
486847.0

因此,我假设486847是x的最大素数因子,但项目欧拉表示不然。我没有看到我的代码或数学中的问题,所以我很困惑。你能看到我不能做的事吗?

9 个答案:

答案 0 :(得分:4)

首先,你必须使用准确的算术手段。其他人建议使用BigInteger。你可以这样做。对我来说,感觉有点像作弊(这对后来处理更大整数的问题更重要)所以更有趣的方式(imho)就是自己编写必要的任意精度操作。

其次,600851475143足够小,可以使用long准确完成,速度会快得多。

第三,你的循环没有正确检查素因子。你只是检查奇数。这是一个准系统(不完整)的解决方案:

long num = 600851475143L;
List<Long> factors = new ArrayList<Long>(); // or use a Set
if (num & 1 == 0) {
  factors.add(2L);
}
for (long i=3; i*i<=num; i+=2) {
  // first check i is prime
  // if i is prime check if it is a factor of num
}

检查某些东西是否具有不同的实施水平。最天真的:

public boolean isPrime(long num) {
  for (long i=2; i<=num; i++) {
    if (num % i == 0) {
      return false;
    }
  }
  return true;
}

当然,这会进行各种不必要的检查。正如您已经确定的那样,您只需要检查最多sqrt(n)的数字,并且您可以消除偶数(2除外):

public boolean isPrime(long num) {
  if (num & 1 == 0) {
    return false; // checks divisibility by 2
  }
  for (long i=3; i*i<=num; i+=2) {
    if (num % i == 0) {
      return false;
    }
  }
  return true;
}

但你也可以做得更好。另一个优化是您只需要在该范围内通过素数检查数字。 63的素数因子是3和7.如果一个数字不能被3或7整除,那么它的定义就不会被63整除。

所以你要做的就是建立一个Set<Long>或素数,直到该平方等于或高于你的目标数。然后只需检查这一系列的数字,以便将其划分为目标。

答案 1 :(得分:2)

对于大值,

double本质上是不准确的,永远不会用于这些类型的数字操作。要使用的正确类是BigInteger,它允许精确表示任意大的整数值。有关浮点数据类型的概述,请参阅this wikipedia article

答案 2 :(得分:1)

首先,使用BigInteger或long而不是double。 Double并不准确,当你遇到后来的问题时,它根本就不正确。

其次,您要打印的是因素,而非主要因素。

这适用于您的情况:

for (double z = 2; z <= x; z++) {
        if (x%z == 0) {
                    while( x%z == 0)
                        x = x/z
                System.out.println(z + "PRIME FACTOR");
        }
}

此外,Project Euler为您提供示例输入和输出。使用它,因为您的代码不会输出与问题中给出的示例匹配的值。

答案 3 :(得分:1)

两件事:

  1. 不要使用double,数字越大,精度越低。相反,您可以使用BigInteger来存储任意大整数,或者在这种情况下,简单的long就足够了。

  2. 您需要在找到它之后除以素数因子,否则您将发现所有因素不仅仅是素因子。像这样:

    if (x % z == 0) {
        System.out.println(z + "PRIME FACTOR");
        x /= z;
        z -= 1; // Might be present multiple times, try it again
    }
    

答案 4 :(得分:0)

public class Prime {
    public static void main(String[] args) {
        double out = 0;
        double m = 600851475143d;
        for (double n = 3; n < m; n += 2) {
            while (m % n == 0) {
                out = n;
                m = m / n;
            }
        }
        System.out.println("" + ((m == 1)?out:m));
    }
}

查看该计划。你会理解算法。这非常简单,非常快。并返回正确答案6857。

答案 5 :(得分:0)

          import java.util.Scanner;

          class Primefactor
                   {
                          public static void main(String args[])
                              {
                       Scanner get=new Scanner(System.in);
                       System.out.println("Enter a number");
                       long number=get.nextLong();
                       int count=0;
                       long input=number;
                             for(long i=number;i>=1;number--)
                                 {
                    for(long j=number;j>=1;j--)
                     {
                       if(i%j==0)
                         {
                            count++;
                         }
                      if(count==2)
                        {
                           if(input%j==0)
                              {
                                 System.out.println(j);
                               }
                           }
                     }
                  }
            }
          }

这是为了查看数据类型限制内任何数字的最大素数因子。

答案 6 :(得分:0)

public static void largestPrimeNo(long lim)
{
long newNum = lim;
long largestFact = 0;

int counter = 2;
while( counter * counter <= newNum )
{
if(newNum % counter == 0)
{
    newNum = newNum / counter;
    largestFact = counter;
}else{
counter++;
}
}
if(newNum > largestFact)
{
largestFact=newNum;
}
System.out.println(largestFact);
}
}

因为Prime no的工作原理是Any integer greater than 1 is either a prime number, or can be written as a unique product of prime numbers。所以我们可以很容易地使用上面的程序。在这个程序中我们除了长的no,找到它的主要因素

答案 7 :(得分:0)

package findlaragestprimefactor;

public class FindLaragestPrimeFactor{

    boolean isPrime(long number) {
        for (long divider = 2; divider <= number / 2; divider++) {
            if (number % divider == 0) {
                return false;
            }

        }
        return true;
    }

    void calculateLargestPrimeFactor() {
        long largestPrimeFactor = 0;
        long x = 600851475143L;
        for(long factor = 3 ; factor <= x/2 ; factor = factor + 2){
            if(x%factor==0 & factor>largestPrimeFactor & isPrime(factor)){
                largestPrimeFactor = factor;
            }
        }
        System.out.println(largestPrimeFactor);
    }







    public static void main(String[] args) {

        MyProject m = new MyProject();
        m.calculateLargestPrimeFactor();
    }
}

答案 8 :(得分:0)

long tNum=600851475143L;

ArrayList<Integer> primeNum=new ArrayList();
System.out.println(10086647/1471);
for(int i=2;i<=tNum;i++) {
    if(tNum%i==0) {
        primeNum.add(i);
        tNum=tNum/i;    
    }
}

System.out.println(primeNum);