项目欧拉#3

时间:2012-11-06 04:57:53

标签: java

问题:

  

13195的主要因素是5,7,13和29。

     

600851475143号码的最大主要因素是什么?

我觉得这个很容易,但运行文件花了很长时间,它已经持续了一段时间,而我所达到的最高数字是716151937。

这是我的代码,我只是要等待或者代码中是否有错误?

        //User made class
public class Three
{   
        public static boolean checkPrime(long p)
        {
            long i;
            boolean prime = false;
        for(i = 2;i<p/2;i++)
        {
            if(p%i==0)
            {
                prime = true;
                break;
            }
        }
    return prime;
    }   

}

    //Note: This is a separate file
public class ThreeMain
{
    public static void main(String[] args)
        {
            long comp = 600851475143L;
            boolean prime;
            long i;
            for(i=2;i<comp/2;i++)
            {
                if(comp%i==0)
                {
                    prime = Three.checkPrime(i);
                    if(prime==true)
                    {
                        System.out.println(i);
                    }
                }
            }
        }       
}

5 个答案:

答案 0 :(得分:1)

你正朝着正确的方向前进,但是你已经走过了你需要去的地方,并且在路上遇到了一些错误。您目前的检查要比验证质数所需的要高得多(特别是素数&gt;&gt; 2)。 您的行for(i = 2;i<p/2;i++)可以是for(i = 2;i*i <= p;i++)(您只需要检查数字的平方根,以确定它是素数还是复合数。)

检查质数的函数实际上对复合材料返回true,而不是质数。你是代码:

    if ((p%i==0) {
        prime = true;
        break; }

应该是

    if ((p%i==0) {
        prime = false;
        break; }

在您的主要方法中,您根本不需要boolean prime。从问题的上下文中,我们可以假设将有两个以上的素因子,这意味着我们需要将comp减少到更小且更易管理的数量的最大素因子是comp的立方根。因此,您的第for(i=2;i<comp/2;i++)行可以是for(i=2;i*i*i<comp;i++)。不是继续检查i是否comp除以后检查i是否为素数,您可以将comp的大小除以i,直至{{} 1}}不再被comp整除(以检查i的权力)。因为您从i的较小值开始,所以如果每次将i减少comp,则永远不会得到除i的复合数字。当您将comp缩减为1时,当前的i将是最重要的因素,也是您解决问题的方法。

另外,你是行:

    prime = Three.checkPrime(i);
    if(prime==true)

可以简化为:

if (Three.checkPrime(i));

因为Three.checkPrime()将返回并最终被评估为布尔值。

答案 1 :(得分:0)

您只需循环播放sqrt(2)代替n/2即可节省大量时间。

答案 2 :(得分:0)

一旦找到了您的号码因素,您可以将其除去以使剩余的数字更小。

if (prime)
{
    System.out.println(i);

    // The factor may occur multiple times, so we need a loop.                
    do {
        comp /= i;
    } while (comp % i == 0);
}

这样做还可以保证只要icompi必须是素数,因为所有较小的素数已经被分割出来,所以你可以删除素数检查:

for (i = 2; i < comp/2; i++)
{
    if (comp % i == 0)
    {
        System.out.println(i);

        do {
            comp /= i;
        } while (comp % i == 0);
    }
}

最后,您只需要检查i直到comp的平方根,因为任何大于平方根的因子必须伴随一个小于平方根的因子。 (即如果i*j == comp,则ij中的一个必须<= comp的平方根。

还有一些技巧可以应用,但这对于这个问题应该足够了。

答案 3 :(得分:0)

你的算法很慢。以下是通过试验分部计算整数的标准方法:

define factors(n)
    f = 2
    while f * f <= n
        if n % f == 0
            output f
            n /= f
        else
            f = f + 1
    output n

有更好的方法来计算整数;你可以在my blog的一篇文章中阅读其中的一些内容。但是这个算法足以让Project Euler#3在大多数现代语言中提供不到一秒的答案。

答案 4 :(得分:0)

这里我写两个不同的逻辑来解决这个问题。我确信它的工作更快

第一个是

import java.util.ArrayList;
import java.util.List;

public class Problem3 {
public void hfactor(long num)
 {
  List<Long> ob =new ArrayList<Long>();
 long working =num;
  long current =2;
  while(working !=1)
   {boolean isprime = true;
    for(Long prime :ob)
    {
      if(current%prime == 0)
       { isprime =false;
         break;   
       }
    }
    if(isprime)
    {ob.add(current);
       if(working%current ==0)
       {
       working /=current;
        }
     } 

  current++;    
    }
    System.out.println(ob.get(ob.size()-1));
   }    


 public static void main(String[] args) {
  Problem3 ob1 =new Problem3();
  ob1.hfactor(13195);
  }
  }

其次是

public static void main(String[] args) {
    List <Long> ob = new ArrayList<Long>(); 
    List<Long> ob1 = new ArrayList<Long>();

    long num =13195;
    for(int i = 2; i<num; i++)
      {
       if (num%i ==0)
         ob.add((long) i);  
      }

    for (int i =0; i<ob.size(); i++)
        for(int j =2; j<ob.get(i); j++)
            {
             if (ob.get(i)%j ==0)
                {
                 ob.set(i, (long) 0);
                    }
             }
           for(int i =0; i<ob.size(); i++){
              if(ob.get(i)!=0)
              {
                 ob1.add(ob.get(i)); 
              } 


             }

        System.out.println(ob1.get(ob1.size()-1));



    }}