当前位置:首页 » 操作系统 » 非质数算法

非质数算法

发布时间: 2024-04-09 08:29:46

A. java 判断是不是素数

判断number是否是素数有这么几种方法:
(1)用2至number-1之间的所有数去整除number,如果有一个能被整除,说明number是非素数;除非所有的数都不能被整除,才说明number是素数。
(2)用2至number/2之间的所有数去整除number,如果有一个能被整除,说明number是非素数;除非所有的数都不能被整除,才说明number是素数。
(3)用2至number的平方根之间的所有数去整除number,如果有一个能被整除,说明number是非素数;除非所有的数都不能被整除,才说明number是素数。

这3种的方法的效率是逐渐提高的。下面列出了第3种方法的实现:
import java.util.Scanner;

public class Test2 {

public static void main(String[] args) {
int number; // 输入的数字

Scanner input = new Scanner(System.in);
System.out.println("请输入数字");
number = input.nextInt(); // 输入数字

if(isPrimeNumber(number)){
System.out.println(number + "是一个素数");
}
else{
System.out.println(number + "是一个非素数");
}
}

public static boolean isPrimeNumber(int num){
if(num < 2){
System.out.println("数据错误");
return false;
}

int k = (int)Math.sqrt(num); //num的平方根
int i;
for(i=2; i<=k; i++){ //依次用2..k之间的数去整除num,如果没有一个数能被整除,说明num是素数
if(num % i == 0){
break;
}
}
if(i > k){
return true;
}
return false;
}
}

如果对你的程序进行修改,也可这样:
public static void main(String[] args) {
int number;// 输入的数字
int j = 2;

Scanner input = new Scanner(System.in);
System.out.println("请输入数字");
number = input.nextInt();// 输入数字

for(j=2;j<number;j++){

if(number%j == 0) {

System.out.println("这不素数");
break;
}
}
if(j>=number)
System.out.println("这是素数");
}

B. 如何知道一个很大的数是不是素数

高速判断用 miller-rabin算法或者 aks 算法

1.约定

x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数。
x^y表示x的y次方。乘方运算的优先级高于乘除和取模,加减的优先级最低。
见到x^y/z这样,就先算乘方,再算除法。
A/B,称为A除以B,也称为B除A。
若A%B=0,即称为A可以被B整除,也称B可以整除A。
A*B表示A乘以B或称A乘B,B乘A,B乘以A……都一样。

2.费马小定理:

有N为任意正整数,P为素数,且N不能被P整除(显然N和P互质),则有:N^P%P=N(即:N的P次方除以P的余数是N)。

但是我查了很多资料见到的公式都是这个样子:

(N^(P-1))%P=1后来分析了一下,两个式子其实是一样的,可以互相变形得到。

原式可化为:(N^P-N)%P=0(即:N的P次方减N可以被P整除,因为由费马小定理知道N的P次方除以P的余数是N)把N提出来一个,N^P就成了你N*(N^(P-1)),那么(N^P-N)%P=0可化为:

(N*(N^(P-1)-1))%P=0
请注意上式,含义是:N*(N^(P-1)-1)可以被P整除

又因为N*(N^(P-1)-1)必能整除N(这不费话么!)
所以,N*(N^(P-1)-1)是N和P的公倍数,小学知识了^_^

又因为前提是N与P互质,而互质数的最小公倍数为它们的乘积,所以一定存在

正整数M使得等式成立:N*(N^(P-1)-1)=M*N*P
两边约去N,化简之:N^(P-1)-1=M*P
因为M是整数,显然:N^(P-1)-1)%P=0即:N^(P-1)%P=1

2.费马小定理:

有N为任意正整数,P为素数,且N不能被P整除(显然N和P互质),则有:N^P%P=N(即:N的P次方除以P的余数是N)。

但是我查了很多资料见到的公式都是这个样子:

(N^(P-1))%P=1后来分析了一下,两个式子其实是一样的,可以互相变形得到。

原式可化为:(N^P-N)%P=0(即:N的P次方减N可以被P整除,因为由费马小定理知道N的P次方除以P的余数是N)把N提出来一个,N^P就成了你N*(N^(P-1)),那么(N^P-N)%P=0可化为:

(N*(N^(P-1)-1))%P=0
请注意上式,含义是:N*(N^(P-1)-1)可以被P整除

又因为N*(N^(P-1)-1)必能整除N(这不费话么!)
所以,N*(N^(P-1)-1)是N和P的公倍数,小学知识了^_^

又因为前提是N与P互质,而互质数的最小公倍数为它们的乘积,所以一定存在

正整数M使得等式成立:N*(N^(P-1)-1)=M*N*P
两边约去N,化简之:N^(P-1)-1=M*P
因为M是整数,显然:N^(P-1)-1)%P=0即:N^(P-1)%P=1

2.费马小定理:

有N为任意正整数,P为素数,且N不能被P整除(显然N和P互质),则有:N^P%P=N(即:N的P次方除以P的余数是N)。

但是我查了很多资料见到的公式都是这个样子:

(N^(P-1))%P=1后来分析了一下,两个式子其实是一样的,可以互相变形得到。

原式可化为:(N^P-N)%P=0(即:N的P次方减N可以被P整除,因为由费马小定理知道N的P次方除以P的余数是N)把N提出来一个,N^P就成了你N*(N^(P-1)),那么(N^P-N)%P=0可化为:

(N*(N^(P-1)-1))%P=0
请注意上式,含义是:N*(N^(P-1)-1)可以被P整除

又因为N*(N^(P-1)-1)必能整除N(这不费话么!)
所以,N*(N^(P-1)-1)是N和P的公倍数,小学知识了^_^

又因为前提是N与P互质,而互质数的最小公倍数为它们的乘积,所以一定存在

正整数M使得等式成立:N*(N^(P-1)-1)=M*N*P
两边约去N,化简之:N^(P-1)-1=M*P
因为M是整数,显然:N^(P-1)-1)%P=0即:N^(P-1)%P=1

3.积模分解公式

先有一个引理,如果有:X%Z=0,即X能被Z整除,则有:(X+Y)%Z=Y%Z
设有X、Y和Z三个正整数,则必有:(X*Y)%Z=((X%Z)*(Y%Z))%Z

想了很长时间才证出来,要分情况讨论才行:

1.当X和Y都比Z大时,必有整数A和B使下面的等式成立:
X=Z*I+A(1)
Y=Z*J+B(2)
不用多说了吧,这是除模运算的性质!
将(1)和(2)代入(X*Y)modZ得:((Z*I+A)(Z*J+B))%Z乘开,再把前三项的Z提一个出来,变形为:(Z*(Z*I*J+I*A+I*B)+A*B)%Z(3)

因为Z*(Z*I*J+I*A+I*B)是Z的整数倍……晕,又来了。
概据引理,(3)式可化简为:(A*B)%Z又因为:A=X%Z,B=Y%Z,代入上面的式子,就成了原式了。

2.当X比Z大而Y比Z小时,一样的转化:
X=Z*I+A
代入(X*Y)%Z得:
(Z*I*Y+A*Y)%Z
根据引理,转化得:(A*Y)%Z
因为A=X%Z,又因为Y=Y%Z,代入上式,即得到原式。
同理,当X比Z小而Y比Z大时,原式也成立。

3.当X比Z小,且Y也比Z小时,X=X%Z,Y=Y%Z,所以原式成立。
=====================================================

4.快速计算乘方的算法

如计算2^13,则传统做法需要进行12次乘法。

[cpp] view plainprint?
  1. /*计算n^p*/
  2. unsigned power(unsigned n,unsigned p)
  3. {
  4. for(int i=0;i<p;i++) n*=n;
  5. return n;
  6. }
/*计算n^p*/
unsignedpower(unsignedn,unsignedp)
{
for(inti=0;i<p;i++)n*=n;
returnn;
}

该死的乘法,是时候优化一下了!把2*2的结果保存起来看看,是不是成了:

4*4*4*4*4*4*2
再把4*4的结果保存起来:16*16*16*2
一共5次运算,分别是2*2、4*4和16*16*16*2

这样分析,我们算法因该是只需要计算一半都不到的乘法了。
为了讲清这个算法,再举一个例子2^7:2*2*2*2*2*2*2
两两分开:(2*2)*(2*2)*(2*2)*2
如果用2*2来计算,那么指数就可以除以2了,不过剩了一个,稍后再单独乘上它。

再次两两分开,指数除以2: ((2*2)*(2*2))*(2*2)*2
实际上最后一个括号里的2 * 2是这回又剩下的,那么,稍后再单独乘上它 现在指数已经为1了,可以计算最终结果了:16*4*2=128

热点内容
安卓系统传奇哪个好玩 发布:2024-11-27 22:26:17 浏览:253
oracle存储过程重命名 发布:2024-11-27 22:12:51 浏览:547
串口服务器几个ip 发布:2024-11-27 21:58:21 浏览:325
麦芒5脚本 发布:2024-11-27 21:45:33 浏览:848
dnf龙猫脚本 发布:2024-11-27 21:45:15 浏览:959
macoutlook存储位置设置 发布:2024-11-27 21:35:15 浏览:810
多台电脑共用一个多口服务器 发布:2024-11-27 21:27:45 浏览:863
算法设计与分析基础课后答案 发布:2024-11-27 21:21:53 浏览:647
linux修改mysql数据库编码 发布:2024-11-27 21:16:48 浏览:626
android10驱动 发布:2024-11-27 21:11:36 浏览:348