• 素数的求法


      一般素数的求法有两种,一种是埃氏筛法,还有一种是线性筛(即欧拉筛法)。

    埃氏筛法(时间复杂度O(nlognlogn))

      给出要筛数值的范围  n,找出  n以内的素数p1,p2,p3,......,pk。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个素数5筛,把5留下,把5的倍数剔除掉;不断重复下去......。

    int m = sqrt (n + 0.5);
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=m;i++)
        if( !vis[i] )
            for(int j=i*i;j<=n;j+=i)
                vis[j]=1;

      用一个数组来储存素数表

    int m = sqrt (n + 0.5); // n + 0.5解决精度问题
    memset(vis,0,sizeof(vis));
    memset(prime,0,sizeof(prime));
    int cnt=1,i;
    for(i=2;i<=m;i++)
        if( !vis[i] ){
            prime[cnt++]=i;
            for(int j=i*i;j<=n;j+=i)
                vis[j]=1;
        }
    
    for(;i<=n;++i){
        if(!vis[i]) prime[cnt++]=i;

    欧拉筛法(O(n))

      埃氏筛法的问题在于他把每个合筛了不只一次,所以我们需要通过优化来使每个合数只需要一遍就能被筛出来,即为欧拉筛法

      

    for( int i = 2 ; i <= n ; ++i ){
            if( IsPrime[ i ] )
                Pri[ PriN++ ]=i; //将这句话放在下面的循环前以保证PriN和Pri值的完整性
            for(int j=0;j<PriN;++j){
                if( i*Pri[ j ] > MaxN )
                    break; //当过大了就跳出
                IsPrime[ i * Pri[ j ] ] = 0;
                //筛去素数
                if( i % Pri[ j ] == 0 ) break;
                //这里是关键,如果i是一个合数(这当然是允许的)而且i mod prime[j] = 0
                //那么跳出,因为i*prime[ (- over -)j ]一定已经被筛去了,被一个素因子比i小的数
            }
        }
  • 相关阅读:
    SQL中JOIN 的用法
    ava中普通代码块,构造代码块,静态代码块区别及示例
    javabean的内省技术和BeanUtils的使用
    Tomcat服务器学习和使用(一)
    增强For循环
    JAVA单态设计模式
    关于枚举的整理
    java中遍历MAP的几种方法
    equals和==的区别
    深入剖析Java中的装箱和拆箱
  • 原文地址:https://www.cnblogs.com/2020pengxiyue/p/9093524.html
Copyright © 2020-2023  润新知