• 数论初步之素数判断


    基本数论-素数判断

     一、暴力求解

      1、一个共识

             x = a*b且x = sqrt(x)*sqrt(x) => a==b==sqrt(x)或者a<sqrt(x) 且 b > sqrt(x),即要么a==b要么一个大于根号x一个小于根号x

         且a = x/b,那么我们只用判断小于sqrt(x)的数是否可以整除x即可。         

      2、暴力求法(O(n^(2/3)))

                    

    bool isPrime(int x){
    for(int i=2;i<=sqrt(x);i++){
    if(x%i==0) return false;
    }
    return true;
    }

    void getPrime(int x){
    for(int i=1;i<=x;i++){
    if(isPrime(i)) cout<<i;
    }
    }

      3、素数普通筛选(n*log(n))

        思想:任何一个素x = 素数*一个数,那么我们可以在找到一个素数的时候,再花n/i的时间去把现在可以确定不是素数的数给标记出来。

        如:已知2是一个素数那么:2,4,6,8,10,12...2*i都不是素数。

        那么时间复杂度为:n/2+n/3+n/5+......+n/p,p为小于n的素数那么渐进时间复杂度为O(n*log(n))

    void getPrime(int x,int* primes){
        for(int i=2;i<=x;i++){
            if(primes[i]==0){
                for(int j=2;j*i<=x;j++)
                    primes[j*i] = 1;
            }
        }
    }

      4、素数筛选之线性筛选(o(n))

        由3我们可以知道,任何一个数字都可以有一个素数乘一个数得到。比如2是素数那么4,6,8,10,12,14,16....2*i都不是素数了,比如3是素数那么6,9,12,15...3*i都不是素数了,我们

        可以看出在我们标记不是素数的时候6,12等在2中标记过,在3中也被标记过这样一来就多了很多重复的操作,那么怎么去优化呢?

        我们最容易想到的就是在int j这个循环中加入,prime[j*i]!=1这个标志,就可以很容易的跳过多余的标记,那么我们总共标记了n个元素所以时间复杂度为O(N).

        

    void getPrimeLine(int x,int* primes){
        for(int i=2;i<=x;i++){
            if(primes[i]==0){
                for(int j=2;j*i<=x&&primes[j*i]!=1;j++)
                    primes[j*i] = 1;
            }
        }
    }

       或者我们可以根据当前的已知的素数来标记如已知 1,2,3,5现在第6次标记就用1,2,3,5分别乘2,3,4,5,6这样每次乘出来的也不一样最终也不会重复标记,因而时间复杂度为O(N)

      

  • 相关阅读:
    Android -- ConditionVariable
    Android -- startActivityForResult和setResult
    StringTokenizer
    Android -- java代码设置margin
    Android -- DisplayMetrics
    Android -- TypedArray
    Android -- 屏幕亮度
    Java assert
    Android -- com.android.providers.media,external.db
    Inno Setup入门(十)——操作注册表
  • 原文地址:https://www.cnblogs.com/jake9402/p/10199567.html
Copyright © 2020-2023  润新知