我试图从http://projecteuler.net解决问题3.但是,当我运行程序时,没有打印出来.
我究竟做错了什么?
问题:600851475143的最大主要因素是什么?
public class project_3
{
public boolean prime(long x) // if x is prime return true
{
boolean bool = false;
for(long count=1L; count<x; count++)
{
if( x%count==0 )
{
bool = false;
break;
}
else { bool = true; }
}
return bool;
}
public static void main(String[] args)
{
long ultprime = 0L; // largest prime value
project_3 object = new project_3();
for(long x=1L; x <= 600851475143L; x++)
{
if( object.prime(x)==true )
{
ultprime = ((x>ultprime) ? x : ultprime);
}
}
System.out.println(ultprime);
}
}
解决方法:
您的主要检查功能不仅总是返回错误;即使它运行正常,你的主循环根本不会寻找输入数字的因子,而只是寻找小于或等于它的最大素数.在伪代码中,您的代码相当于:
foo(n):
x := 0 ;
foreach d from 1 to n step 1:
if is_prime(d): // always false
x := d
return x // always 0
is_prime(d):
not( d % 1 == 0 ) // always false
但是你根本不需要素数检查功能.以下查找数字的所有因子,到trial division:
factors(n):
fs := []
d := 2
while ( d <= n/d ):
if ( n % d == 0 ): { n := n/d ; fs := append(fs,d) }
else: { d := d+1 }
if ( n > 1 ): { fs := append(fs, n) }
return fs
可分性测试仅在数字的平方根处进行.如所发现的,每个因子被分解出被分解的数量,从而进一步减少了运行时间.所涉及数量的因子分解立即运行,仅需1473次迭代.
通过构造,所发现的所有因素都保证是素数(这就是为什么不需要进行素数检查的原因).为了实现这一点,按升序计算可能的除数至关重要1.升序也是最有效的,因为任何给定的数字更可能具有比较大的素数小的素因子.枚举素数代替赔率,虽然没有必要,但如果你有一种有效的方法来获得这些素数,那么它将更有效率.
增加上述内容以找到最大因素是微不足道的:只需实现追加为
append(fs,d):
return d
1
因为当原始数的任何复合除数d被分解时,当我们达到d时,我们已经将它的素因子除以原始数,因此减少的数将与它没有共同的素因子,即即使它除了原始数字,d也不会将减少的数字分开.