1、引言
素数又叫质数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
0和1既不是质数也不是合数,最小的质数是2。
学过计算机编程语言(如C语言)的小伙伴应该都有一点了解,那么如何判断一个自然数是不是素数呢?
楼主分享了以下不同的版本
1.普通版
//注意用良好的英文释义表示,初学者常容易随性用中文式拼音表达,例如以下函数命名
bool IsSushu(int num)
{
if( num == 2)
return true;
for (int i = 2; i < num; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
结合自然数及素数的判断性质,对自然数2应特殊处理。
然后我们只需要从2开始,依次判断是否能被 i 整除,如果能,则不是素数,循环结束若都没有被整除过,那么就是素数。
2.优化版本
我们注意到对于自然数n,除去1和自身外,分解成两个因数相乘,一定是一个因数 n1 ≤ sqrt(n),另外一个因数 n2 ≥ sqrt(n),因此我们做整除判断不必判断到 n - 1,只需要判断到 sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。
bool IsPrime(int num)
{
if (num == 2)
return true;
int k = sqrt(num);
for (int i = 2; i <= k; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
3.其他优化版本
关于上面的算法还可以进一步优化,我们只需要判断针对大于2的奇数,即优化循环体内除数自增的步长,因为大于2的偶数一定能被2整除,整理了一下,最终给出以下算法:
//使用良好的英文表达
bool IsPrime(int candidate)
{
if ((candidate & 1) != 0)
{
int limit = sqrt(candidate);
for (int divisor = 3; divisor <= limit; divisor += 2)
{
if (candidate % divisor == 0)
return false;
}
return true;
}
return (candidate == 2);
}
当然,网上还有一些专门根据素数分布规律:大于5的质数一定与6的倍数相邻,除去6n±2等非验证项,只需验证 6n-1与6n+1的相关算法,感兴趣的小伙伴可以研究一下,其实也是优化了除数的自增步长,因此不在此赘述。
我们从最基本的判断素数算法可以看到不同的版本有着不同的思维方式,面对复杂的算法更值得我们从多方面分析。