我需要做一个算法来检查一个数字是否是素数,并且模数检查最少。我需要尽可能少的模运算。
static int counter = 0;
static bool isPrime(double n)
{
if (n <= 1) { return false; }
if (n <= 3) { return true; }
counter += 2;
if (n % 2 == 0 || n % 3 == 0) { return false; }
for (int i = 5; i * i <= n; i = i + 6)
{
counter += 2;
if (n % i == 0 || n % (i + 2) == 0)
{
return false;
}
}
return true;
}
答案 0 :(得分:2)
第一个问题是这个问题非常不明确。让我澄清一下。
算法通过如下划分测试来测试素数:
这个算法很聪明,因为它会跳过检查所有偶数,这些数字已经通过查看2的可分性来检查,并且还跳过所有除以3可被3整除的奇数,如9,15,21等等。 / p>
问题是它 检查25,即使已经检查了5。它也将检查35,即使已经检查了5和7。
您可以使用此算法执行的最佳仅按素数进行可分性检查。这就是这些神秘数字的来源:
1009 - 11 mod,10091 - 25 mod,100913 - 66 mod
有11个主要因素要测试小于1009的平方根。有25个主要因素要测试小于10091的平方根,依此类推。
解决方案是预先计算一个小素数表,无论你需要多少。一千,说。您可以花费尽可能多的时间,因为您只需要执行一次,然后将其添加到您的程序中:
int[] primes = { 2, 3, 5, 7, 11, 13, 17, ... }
现在您的算法非常简单:
static class Extensions {
public static bool IsPrime(this int n)
{
if (n <= 1) return false;
foreach(int prime in primes)
{
if (prime * (long)prime > (long)n) return true;
if (n % prime == 0) return false;
}
throw new Exception("primes array is too small!");
}
}
练习为什么我会施展到很长时间?
练习 primes
数组必须有多大才能确保每个可能的输入都能提供正确的答案而不会抛出?如果n
是long
而不是int
,那么有多少呢? (提示:为您提供小于数字的素数的函数称为素数计数函数;您对它有什么了解吗?)
答案 1 :(得分:0)
即使我不理解您的问题,您也可以查看Zoran Horvat的以下Link。
该网站提供了一个很好的分析,如何测试是一个数字素数。除了提供的链接,该网站包含更多相同主题的内容。
以下是代码段(请查看链接以获取更多信息)
static bool IsPrime(int n)
{
bool result = false;
if (n <= 3)
{
result = true;
}
else if (n % 2 != 0 && n % 3 != 0)
{
int k = 5;
int step = 2;
while (k * k <= n && n % k != 0)
{
k = k + step;
step = 6 - step;
}
if (n == k || n % k != 0)
result = true;
}
return result;
}
希望这会有所帮助。快乐的编码!
PS: