在网上看到很多找质数的算法,都是检查从2到n-1的数能否被n整除,能就不是质数,反之就是素数,这样做当然是正确的,但是浪费了一些没有必要的检查,其实只要检查从2到sqrt(n)之间的数就可以了,因为如果一个数有因子的话,那么它必定有一个因子不大于该数的平方根。
public static void PrimeNum(int maxNum)
{
for (int i = 3; i <= maxNum; i++)
{
bool IsPrime = true;
for (int j = 2; j <= Math.Sqrt(i); j++)
{
if (i % j == 0)
{
IsPrime = false;
break;//有因子证明是合数,马上退出循环。
}
}
if (IsPrime)
{
Console.Write(i.ToString()+" ");
}
}
}
筛法将会是一个更优的算法,请参见我的另一篇文章:
例如要查找100以内的质数,首先2是质数,把2的倍数去掉;此时3没有被去掉,可认为是质数,所以把3的倍数去掉;再到5,再到7,7之后呢,因为8,9,10刚才都被去掉了,而100以内的任意合数肯定都有一个因子小于10(100的开方),所以,去掉,2,3,5,7的倍数后剩下的都是质数了。
用程序可以这样解决,引入布尔类型数组a[i],如果i是质数,a[i]=true,否则a[i]=false。那么划掉i可以表示成a[i]=false。
//找出n以内质数
void Sieve(int n)
{
bool[] a = new bool[n+1];
for (int i = 2; i <= n; i++) a[i] = true;
for (int i = 2; i <= Math.Sqrt(n); i++)
{
if (a[i])
for (int j = i; j*i <= n; j++) a[j * i] = false;
}
for (int i = 0; i <= n; i++)
{
if (a[i])
Console.Write("{0},",i.ToString());
}
}
如果去掉最后一个用来显示结果的循环的话,运行Sieve(10000000)只要1秒多,而上次那个算法PrimeNum(10000000)却要71秒多!
http://www.cnblogs.com/guoxiaocong/archive/2005/12/27/305611.html