我没有发现我的程序有任何问题。请指出我的错误并帮助我。
代码如下:
class largest
{
public static void main(String...args)
{
double n,i,f=1.0;
n=600851475143L;
largest ob= new largest();
for(i=n/4;i<n/2;i++)
{
if(n%i==0)
{
if(ob.isprime(i) == 1)
f=i;
}
}
System.out.println(f);
}
int isprime(double k)
{
int s,i=2,flag=0;
while(i<k && flag==0)
{
if(k%i==0)
flag=1;
}
if(flag==0)
return 1;
else
return 0;
}
}
答案 0 :(得分:5)
您的函数isprime
在大多数情况下是无限循环。它永远不会在循环中增加i
。
每次编写循环时,都应该考虑所谓的loop variant。这是循环的数字属性,即:
如果你不能想到这样的财产,你就会遇到大麻烦,因为你很可能会有无限循环。
在您的示例中,该属性应该是您想要的素数因子减去您正在检查的当前素因子候选者的数字。
在你当前的代码中,如果你计算循环变量,你将得到一个正整数(好),但它不会减少(坏)。因此,你将永远等待,因为你有一个无限循环。
虽然其他答案显示了很好的解决方案,可以让您的代码更有效率,但这对您无非常有帮助:一个有效的无限循环仍然无法为您提供任何结果。
答案 1 :(得分:1)
你的代码太慢了,这就是为什么它需要花费很多时间来执行并且不会返回任何输出(显然)。你应该使用以下技巧加快你的isPrime
测试:如果n不是素数,它可以写成n = p x q其中p <= sqrt(n)和q&gt;页。然后,你可以在sqrt(n)停止你的循环,因为如果没有整数p&lt; = sqrt(n)验证这个属性你能告诉n不是素数。
以下代码使用该注释,但也使用另一个属性:一个整数总是可以写成6 * p + q,其中p和q是整数,q&lt; 6.对于所有p,6 * p + 2和6 * p + 4可被2整除,6 * p + 3可被3整除,因此对于所有n = 6 * p + q,如果n不能被2除尽也不到3时,n的形式为6 * p + 1,即6 * p + 5(或6 * p - 1,相当于)。
public static boolean isPrime(int n) {
if (n == 2 || n == 3)
return true;
if(n <= 1 || n % 2 == 0 || n % 3 == 0)
return false;
int x = (int) Math.sqrt(n);
for(int i=1 ; (6*i-1) <= x ; i++)
if(n % (6*i-1) == 0 || n % (6*i+1) == 0)
return false;
return true;
}
修改:
另外,正如stefan.schwetschke所观察到的那样,你没有递增循环的索引。在这种情况下,您应该使用for循环,因为您现在正好是循环索引的边界。
答案 2 :(得分:0)
这不是“代码”答案(其他答案都不会在合理的时间内提供解决方案,即使在纠正您的暴力原始代码时也是如此)。
您可能希望使用Pollard-Strassen算法(或Rho Pollard算法)来探索素数因子分解算法。
一些研究链接包括:
和https://math.stackexchange.com/questions/185524/pollard-strassen-algorithm (对于stackexchange上的数学。