如何找到小于n的最大素数,其中n≤10? 请帮我找一个高效的算法。
for(j=n;j>=2;j--) {
if(j%2 == 1) {
double m = double(j);
double a = (m-1)/6.0;
double b = (m-5)/6.0;
if( a-(int)a == 0 || b-(int)b == 0 ) {
printf("%llu\n",j);
break;
}
}
}
我使用了这种方法,但是对于n> 10 ^ 10;
来说,这是无效的如何优化这个..
修改 解决方案:对每个j使用Primality测试。
答案 0 :(得分:7)
我不认为这个问题应该如此迅速地被驳回,因为效率不容易确定这个范围内的数字。首先,鉴于平均素数差距为ln(p)
,从给定的(n)
开始向下是有意义的。即,ln(10^18) ~ 41.44)
,因此您可以预期从41
开始平均平均期间(n)
次迭代。例如,测试:(n), (n - 2), (n - 4), ...
鉴于此平均值差距,下一步是决定是否要使用天真测试 - 通过素数<= floor(sqrt(n))
检查可分性。使用n <= (10^18)
,您需要针对素数<= (10^9)
进行测试。此范围内有~ 50 million个素数。如果您愿意对这些值进行预计算和制表(所有这些值都适合32位),则可以对64位值n <= 10^18
进行合理的测试。在这种情况下,200MB素数表是否可以接受? 20年前,它可能不会。今天,这不是问题。
将主表与筛选和/或Pocklington's test相结合可能会提高效率。或者,如果内存受到更多约束,则Miller-Rabin test的确定性变体带有基数:2, 325, 9375, 28178, 450775, 9780504, 1795265022
(SPRP set)。大多数复合材料在SPRP-2测试中立即失效。
重点是 - 您决定在算法复杂性之间做出理论和实施难度,以及与空间/时间权衡的平衡。