今天讲点比较高级的算法,目的也很简单,求质数,但是应用一种新的算法Miller-Rabin算法,这是一种利用了概率和费马小定理的算法设计,有点玄乎吧,其实本人也是刚接触这种算法,这是一种纯数学的解法,如果各位不懂,当学习一下数学也好啊好,我们往下讲
首先了解基本的数学知识,费马小定理:
若n是素数,则对所有1≤a≤n-1的整数a,有a^(n-1)mod n=1;
作者Fermat 很牛的数学家,在他在世的时候好像还没有计算机,不过今天我们要用这个定理来设计算法
分析这个定理可以知道,如果一个数是质数,那么它必定满足任意一个整数属于(1,n-1)范围有a^(n-1)mod n=1,不懂?我们取逆否命题试试看,就是只要存在在(1,n-1)范围中的整数a 使得a^(n-1)mod n=1不成立,那么这个数就不是素数,相信明白了吧,我们要确定一个数是否是素数,只要随机生成一系列的数a,如果这些数a使N满足费马小定理的话那么就可以认定它是素数了,当然有个前提,就是这个推导只能在计算机领域内使用就跟我上次讲的用哥德巴赫猜想优化一道算法题目一样,在计算机可以运算的数的范围内可用,请不要在其他科学领域类使用
算法如下,原本是网络上的一个C++算法,我改成C
/**费马小定理的应用,求质数*Miller-Rabin算法*2008 12 27*/#include"stdio.h"#include"stdlib.h"#include"math.h"#include"time.h"int Btest(int a,int n){ int s = 0; int t = n-1; int i , j , k; int x = 1; int y; i = 1; do{ s++; t = t / 2; }while((t%2)!=1); while(i < tbr> x = ( x * a ) % n; i++; } if((x == 1) || ( x == n-1)) return 1; for(j = 1 ; j < s - jbr> y = 1; for(k = 1 ; k < j kbr> { y = 2 * y; } i = 1; x = 1; while(i < y tbr> x = ( x * a) % n; i++; } if(x == n - 1) return 1; } return 0;}int MillRab(int n){ int a; /*利用时间作为随机种子产生随机数*/ a=random((unsigned)time(0))%(n-3)+2; return Btest(a,n);}int MillerRabin(int n,int k){ int i; for(i=1;i< kibr> { if(MillRab(n)==0)return 0; } return 1;}int main(){/*费马小定理的应用*/ int i; int n=10000;/*定义测试范围*/ int count=0; printf("2 3 ");/*先输出2跟3*/ for(i=5;i< nbr> if(MillerRabin(i , (int)log10(i))){/*符合条件?*/ printf("%d ",i); count++; } i=i+2; } printf("nthere %d prime(s)n",count); return 0;}
--------------------------------------------------------------------------------------
- 版权声明:
- 如在本页面内无特别说明,本文内容均为[李大仁博客]原创,本文版权归[李大仁博客]所有。
- 欢迎转载,转载请务必在文章页面明显位置提供原文链接并注明出处。欢迎您在转载本文时保留本段声明。
- 文章标题:
[算法]费马小定理求质数的算法之Miller-Rabin算法,C语言实现
- 独立博客:
李大仁博客
- 永久链接:http://www.lidaren.com/archives/277
--------------------------------------------------------------------------------------
以上内容由博客自动发布工具自动发布,最终显示内容和效果会与原文内容有所偏差,敬请谅解。
转载请注明原文地址: https://ju.6miu.com/read-1307326.html