质数,又称“素数”,质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
现在,ljn教大家如何用程序判断质数。
1.一般,大家在程序中判断质数都是写一个函数,函数中循环从2到这个数的算数平方根枚举,看看这个数是否能整除枚举的数,如果能,则是质数,反之合数。
C Code:
int pd(int n) {
int i;
for(i=2; i<=floor(sqrt(n)); i++)
if(n%i==0) return 0;
return 1;
}
C++ Code:
bool pd(int n) {
for(int i=2; i<=floor(sqrt(n)); i++)
if(n%i==0) return 0;
return 1;
}
Pascal Code:
Function pd(n:longint):boolean;
var i:longint;
begin
for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then exit(false);
exit(true);
end;
注:C/C++ Code中,调用了floor函数,Pascal Code中,调用了trunc函数,它们都是把浮点数的小数部分去掉(不是四舍五入)。
C/C++和Pascal的sqrt函数是求一个数的算术平方根。
C/C++的floor函数和sqrt函数均在头文件<math.h>中。
2.接下来介绍一种Monte-Carlo算法:
如果n是一个正整数,如果a^(n-1))≡1(mod n),我们说n是基于a的伪素数。如果一个数是伪素数,它几乎肯定是素数。另一方面,如果一个数不是伪素数,它一定不是素数。由于我们可以自由地选取基,所以如果在选取了s个基后发现n都是伪素数,就几乎可以肯定n是素数了。
它最简单的实现方法是一个驯循环,时间复杂度为O(s),s越大,准确率越高。
Pascal Code:
Function MR(n:longint):boolean;
var i,a:longint;
begin
for i:=1 to s do
begin
a:=random(n-2)+2;
if modular_exp(a,n-1,n)<>1 then exit(false);
end;
exit(true);
end;
注:此处调用了modular_exp函数,即计算a^b mod c的值。
这种思路也可以采用二进制扫描法快速地计算出a^b mod c的值。根据模算术的基本知识,(a*b)mod c=((a mod c)*b)mod c,那么可以把a^b mod c变成一系列较小数的乘积。把b写成二进制(a[t],a[t-1]…,a[1],a[0])。
这样,有:a^b mod c=a^(a[t]*2^t+a[t-1]*2^(t-1)+…+a[1]*2^1+a[0]*2^0)mod c=((a^(a[0]*2^0)mod c)*(a^(a[1]*2^1)mod c)*…*(a^(a[t]*2^t)mod c))mod c。
总时间复杂度为O(log3(b))。
原文地址:https://www.cnblogs.com/ljnoit/p/9536585.html