精华内容
下载资源
问答
  • 素数算法素数代码

    2011-12-22 13:00:22
    素数算法素数代码
  • 算法 素数筛法

    2016-03-18 10:52:15
    素数筛法是ACM 及各大比赛中必须熟练掌握的最低级的算法,在已知某些素数的情况下对未判断的数进行筛选,筛选掉必然不是素数的数。如何对数进行筛选,依据素数的性质,某个除1以外的正整数是素数,则该数的倍数一定...

    素数筛法

    关键思想

    素数筛法是ACM 及各大比赛中必须熟练掌握的最低级的算法,在已知某些素数的情况下对未判断的数进行筛选,筛选掉必然不是素数的数。如何对数进行筛选,依据素数的性质,某个除1以外的正整数是素数,则该数的倍数一定不是素数

    举个栗子

    从1-10中筛选出所有素数

    步骤当前元素12345678910
    原始数组//000000000
    第一步2/001010101
    第二步3/001010111
    第三步5/001010111
    第四步7/001010111

    以第一步为例:当前元素为2,则将 22=4 23=6 25=10 都置为合数,即每次都将当前为素数的元素的倍数从候选的数中除去。
    循环上述过程,则可得到最终的数组,数组中为0的则该元素为素数,否则为合数。

    代码如下

    #include <cstdio>
    #define MAXN 11
    int prime[MAXN] = {1, 1}; //第0,1个元素直接设为合数,合数设为1,素数为0
    int main() {
        //素数筛法求素数
        for (int i = 0; i < MAXN; ++i) {
            if (!prime[i]) {//若该数是素数,则将该数的倍数全设为合数。
                //printf("%d ",i); 答应当前元素
                for (int j = 2 * i;  j <= MAXN; j+=i) {//筛选掉必然是合数的数
                    prime[j] = 1;
                }
            }
        }
        return 0;
    }

    复杂度

    该算法的复杂度为 O(n2) ,但常系数非常小,实际运行时接近 O(N) 复杂度,并且随着筛选的进行,可以仔细思考一下,最后筛选掉的数越来越多,剩下的素数越来越小,即素数之间的间隔越来越大。

    关于优化

    在素数筛法的过程中,有许多重复计算的过程可以进行优化,例如上述例子中,元素6和元素10都筛选了两次,就是表格中红了两次。
    下边列一下可以优化的点,就不具体实现了。
    1. 避免重复筛选
    2. 偶数直接可以不参与筛选,并且依据这个规则可以将数组大小优化掉一半
    说明一下第二点可以优化空间的方法,例如原数组的第 i 个元素代表数字i是否为素数,若直接将偶数去除,则数组的第i个元素则可代表数字 2i1 是否为素数。

    进阶

    想继续学习素数有关知识的可以看看以下几个知识点

    1. 费马测试
    2. Miller-Rabin 质数测试
    3. 欧拉-雅科比测试
    4. AKS质数测试

    等等素性测试算法,可能以后会在详细讨论这些算法。

    展开全文
  • Erathosthenes算法,它的工作方式如下:输入一个从整数2到N的列表,数字2是第一个质数。所有和2有倍数关系的数字如4,6,8等都不是质数,我们把这些数从列表中排除。接着,2之后的第一个未被删除的数是3,它是第二个...

    Erathosthenes算法,它的工作方式如下:输入一个从整数2到N的列表,数字2是第一个质数。所有和2有倍数关系的数字如4,6,8等都不是质数,我们把这些数从列表中排除。接着,2之后的第一个未被删除的数是3,它是第二个质数。所有和3有倍乘关系的数都不是质数,从列表中排除这些数。注意,6已经被排除了,9和12也已经离开了,还有15等。上下的没有被排除的第一个数是接下来的一个质数。算法以这种方式继续运行,直到达到最后一个数N。最后剩下来的数都是质数。

    代码:数组实现

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const ll N=1000000+10;
    ll prime[N],arr[N],cnt=0;
    int main()
    {
        ll n; //指定范围1~n
        while(scanf("%I64d",&n)==1)  //连续输入
        {
            cnt=0;
            memset(arr,0,sizeof(arr));
            for(ll i=2;i<=n;i++)
            {
                if(!arr[i])
                   prime[cnt++]=i;
                for(ll j=i*2;j<=n;j+=i)
                   arr[j]=1;
            }
            for(ll i=0;i<cnt;i++)
                cout<<prime[i]<<" ";   //输出1~n范围内的所有质数
            cout<<endl;
        }
    }
    


    vector实现:

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const ll N=1000000+10;
    ll prime[N],arr[N],cnt=0;
    int main()
    {
        ll n; //指定范围1~n
        vector<int> container;
        while(scanf("%I64d",&n)==1)  //连续输入
        {
            cnt=0;
            memset(arr,0,sizeof(arr));
            for(ll i=2;i<=n;i++)
            {
                if(!arr[i])
                   container.push_back(i);
                for(ll j=i*2;j<=n;j+=i)
                   arr[j]=1;
            }
            vector<int>::iterator p;
            for(p=container.begin();p!=container.end();p++)
                cout<<*p<<" ";   //输出1~n范围内的所有质数
            cout<<endl;
        }
    }


    改进:

    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const ll N=1000000+10;
    ll prime[N],arr[N],cnt=0,n;
    bool B(ll n)
    {
        for(int i=0;prime[i]*prime[i]<=n;i++)
        {
            if(n%prime[i]==0)
                return false;
            return true;
        }
    }
    int main()
    {
        //指定范围1~n
        while(scanf("%I64d",&n)==1)  //连续输入
        {
            cnt=0;
            memset(arr,0,sizeof(arr));
            ll k=(ll)floor(sqrt(n)+0.5);
            for(ll i=2;i<=n;i++)
            {
                if(!arr[i])
                       prime[cnt++]=i;
                for(ll j=0;j<cnt&&prime[j]*i<=n;j++)
                {
                       arr[prime[j]*i]=1;
                       if(i%prime[j]==0) break;
                }
            }
            for(ll i=0;i<cnt;i++)
                cout<<prime[i]<<" ";   //输出1~n范围内的所有质数
    
            cout<<endl;
        }
    }
    


    展开全文
  • Miller_Rabin算法 素数判定

    千次阅读 2018-07-13 23:16:18
    算法理论基础  Miller-Rabin算法是Fermat算法的一个变形改进,它的理论基础是由Fermat定理引申而来。... Miller-Rabin 算法的理论基础:如果n是一个奇素数, 将n-1表示成2^s*r的形式(r是奇 数),a 是和n...

     

    算法理论基础

           Miller-Rabin算法是Fermat算法的一个变形改进,它的理论基础是由Fermat定理引申而来。

     

      Fermat 定理: n是一个奇素数,a是任何整数(1≤ a≤n-1) ,则 a^(n-1)≡1(mod n)。

     

      Miller-Rabin 算法的理论基础:如果n是一个奇素数, 将n-1表示成2^s*r的形式(r是奇 数),a 是和n互素的任何整数, 那么a^r≡1(mod n) 或者对某个j(0≤j ≤s -1, j∈Z) 等式 a^(2^j*r) ≡-1(mod n)成立。 这个理论是通过一个事实经由Fermat定理推导而来: n是一个奇素数,则方程x^2 ≡ 1 mod n只有±1两个解。

    重复n次实验。对于每一次实验,随机取检验算子a,带入定理进行检验,看看在算子a下,n能否满足

     

    a^r ≡ 1 mod n或者对某个j (0 ≤ j≤ s−1, j∈Z) 等式a^(2jr) ≡ −1 mod n       **

    如果任意一次实验不满足,则判定不是素数,如果都满足,可近似可以认为是素数(错误率极小)。

     

    取模运算性质

    术语:

    For a positive integer n, two integers a and b are said to be congruent modulo n, and written as

    一些有用的性质(可证明):

    如果a≡b(mod m),x≡y(mod m),则a+x≡b+y(mod m)。

    如果a≡b(mod m),x≡y(mod m),则ax≡by(mod m)。

    如果ac≡bc(mod m),且c和m互质,则a≡b(mod m) (就是说同余式两边可以同时除以一个和模数互质的数)。

    #include <iostream> 
    #include <algorithm>  
    #include <cstring>  
    #include <map> 
    using namespace std;
    
    typedef unsigned long long ll;//10^20 左右再大我也很无奈=.= 
    const int times = 10;//一般10就够了
    int prime[] = {2, 3, 5, 7, 13, 17, 11, 61, 97, 24251, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 67, 71, 73, 79, 83, 89};		//得到随机检验算子 a
    
    ll  Random(ll n){
    	return (double(rand())/RAND_MAX * n+0.5);
    }
    
    ll q_mul(ll a, ll b, ll mod){
    	ll ans=0;
    	while(b){
    		if(b & 1)	ans=(ans+a)%mod;
    		a=(a<<1)%mod;
    		b>>=1;
    	}
    	return ans;
    //	return (a*b)%mod;//超时就换成这个 
    }
    
    ll q_pow(ll a, ll b, ll mod){
    	ll ans=1;
    	while(b){
    		if(b & 1)	ans=q_mul(ans,a,mod);
    		a=q_mul(a,a,mod);
    		b>>=1;
    	}
    	return ans;
    }
    
    bool miller_rabin(ll n){				 //检验n是否是素数
    	if(n<2) return false;
    	if(n==2) return true;
    	if(!(n&1)) return false;				//如果是2则是素数,如果<2或者是>2的偶数则不是素数
    	
    	ll k,j=0, x, tem = n-1;
    	while(!(tem & 1)) tem>>=1,j++;
    	for(int i=0;i<times;i++){				//做times次随机检验
    		if(prime[i] >= n) return true;
    		x = q_pow(prime[i], tem, n);				//得到a^r mod n
    		if( x == 1 ) continue;			//余数为1则为素数
    		for(k=0;k<j;k++){		
    			if(x == n-1) break;			//否则试验条件2看是否有满足的 j
    			x = q_mul(x, x, n);
    		}
    		if(k == j) return false;
    	}
    	return true;
    }
    
    int main( )
    {
    	long long tar;
    	while(scanf("%lld",&tar)){
    		if(miller_rabin( tar ))	//检验tar是不是素数
    			cout << "Yes, Prime!" << endl;
    		else
    			cout << "No, not prime.." << endl;
    	}
    	return 0;
    }
    

    再大就要手动实现大整数了。。。太麻烦了,可以用java里的BigInteger,里面提供了一个实现这个算法的方法,方法原型是:

    boolean isProbablePrime(int certainty)

     

    参考:https://blog.csdn.net/maxichu/article/details/45458569点击打开链接

    https://blog.csdn.net/chensilly8888/article/details/42834697

    展开全文
  • 随机算法 素数测试

    千次阅读 2008-10-29 22:34:00
    素数测试费马定理进行素数测试如果n不能整除a则有a^(n-1) mod n = 1,通过判断费马定理的模等式是否成立就可以判断一个数是不是合数(显然,如果一个数是合数那么等式一定不成立)但是,如果等式成立,n还是有可能是...

    素数测试

    费马定理进行素数测试
    如果n不能整除a则有a^(n-1) mod n = 1,通过判断费马定理的模等式是否成立就可以判断
    一个数是不是合数(显然,如果一个数是合数那么等式一定不成立)但是,如果等式成立,
    n还是有可能是合数(伪素数:1387等)。

    MillerRabin素数测试
    基于:1,a^(n-1) mod n = 1,2,x^2 mod n = 1;
    通过以下几个手段达到更好的测试效果:
    1, 随机选择a
    2, 如果在运行a^(n-1) mod n = 1的过程中,发现x^2 mod n = 1成立,那么n肯定是
    合数,就没有必要继续下去。通过一下具体过程实施:
    将a^(n-1) mod n = 1中的幂n-1分成n-1=2^t*u,基于a^(xy)mod n = ((a^x)mod n *(a^y)mod n)mod n,
    所以先算m = a^u,然后在循环中计算p = (m^(t/2)*m^(t/2))mod n这样,如果p=1,
    并且m^(t/2)!=1&&m^(t/2)!=n-1则根据x^2 mod n = 1,有n一定是一个合数。这样就不需要继续测试下去了。

    MillerRabin素数测试程序:点击此处

     

     

    展开全文
  • 算法素数(质数)判断方法

    万次阅读 多人点赞 2017-11-29 17:05:32
    素数(质数)的判断在算法问题中经常遇到,这里小结几种常用的判断方法。首先,我们来看一下素数(质数)的定义:质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。...
  • 质数素数算法,及算法优化

    千次阅读 多人点赞 2019-08-11 10:47:29
    质数素数):只能被1和其本身整除的数字(其中1和0不属于质数) 接下来我们用多种方法求1000以内(包含1000)的质数数量,并且统计每种方法的循环次数 (如果只想知道速度快的方法可以直接看方法五) 方法一: 循环...
  • VB常用算法素数 VB常用算法素数 VB常用算法素数 VB常考算法素数 1算法说明 所谓素数是指只能被1和它本身整除的数 1判断某数是否为素数根据循环控制变量来判断 算法说明根据素数只能被1和它本身整除的性质我们可以...
  • 素数定义 素数判定证明 素数求解算法 素数定义 素数判定证明 素数求解算法
  • 文章目录Python 如何求素数、质数素数、质数(重点)方法一:枚举方法二:厄拉多塞筛法【埃氏筛】方法三:线性筛相关博客 素数、质数(重点) 先明白什么是素数 质数,英文名:Prime number,又称为素数,指的是值大于1...
  • 素数质数算法 如果一个正整数只有两个因子,1和p,则p为素数 1、根据概念判断 bool isPrime(int n) { if(n < 2) return false; for(int i = 2; i < n; ++i) if(n%i == 0) return false; r...
  • 定义:约数只有1和本身的整数称为质数,或称素数。 计算机或者相关专业,基本上大一新生开始学编程都会接触的一个问题就是判断质数,下面分享几个判断方法,从普通到高效。1)直观判断法最直观的方法,根据定义,...
  • 素数算法

    2020-12-22 16:14:10
    * 素数又叫质数质数是指在大于1的自然数中,除了1和它本身以外,不能被其他自然数整除的数。 * 参考文档: * https://www.zifangsky.cn/89.html * https://blog.csdn.net/program_think/article/details
  • 最近看到一篇高效的素数判断算法文章,但是文章中有些部分写的还不够完整清晰,所以在此详细记录一下此算法理解过程。(理解此算法前应先明白使用 sqrt(num) 为判断条件判断素数的方法) 此算法产生的原因(定理):...
  • 质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数; Java代码实现: 在一般领域,对正整数n,如果用 2到 之间的所有整数去除,均无法整除,则n为质数质数大于等于2 不...
  • 首先看看质数或者素数的概念: 素数质数是没有区别的。质数(又称素数),是指在大于1的自然数中,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数质数)。比1大但不是素数的数称为合数,1和0...
  • 回溯算法素数环问题 问题描述 素数环:从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数算法分析 【算法流程】 1、数据初始化; 2、递归填数:判断第i个数填入是否合法; A、如果合法:填数;判断是否...
  • 素数判定算法的实现

    2021-01-20 05:52:18
    2. 原始算法 素数的定义是,除了能被1和它本身整除而不能被其他任何数整除的数。根据素数定义 只需要用2到n-1去除n,如果都除不尽,则n是素数,否则,只要其中有一个数能整除则n不是素数。 代码如下: bool is_...
  • 其实这道题不必用MR算法,直接暴力sqrt(n)判断一个数是否为质数可过。先说这道题,为什么要用到判断一个数是否为质数。a, b的范围是1亿,所以先筛素数再判断每个素数是否回文数是行不通的。所以要先生成所有的回文数...
  • 质数素数算法

    2019-10-30 23:05:30
    /** ...素数:质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数</pre> * @作者 xingsfdz xingsfdz@163.com * @创建时间 2019年10月30日 下午10:4...
  • 判断101-300之间有多少个素数质数),并输出所有素数
  • aks算法判定素数

    2018-04-19 11:31:10
    Manindra Agrawal教授和他的两个学生Neeraj Kayal和Nitin Saxena在坎普尔印度技术研究...AKS算法证明了可以应用一个确定的算法在输入规模的多项式时间内决定一个整数是否为素数的问题,而没有使用任何未证明的数学假定
  • 质数算法

    2015-07-27 10:44:52
    15.7.27 质数算法基础
  • 质数素数)判断: from math import sqrt def is_prime(n): if n==1: returnFalse for i in range...
  • 目录质数素数)的寻找算法优化代码优化过程优化完成代码 质数素数)的寻找算法优化 质数(素数)的概念: 简单的理解: 就是只能够被1和它本身整除的数。 需求: 查找任意给定整数N范围内的所有质数素数 ) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 74,646
精华内容 29,858
关键字:

算法质数