求素数的高效实现

Posted zhengmengen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求素数的高效实现相关的知识,希望对你有一定的参考价值。

对于给定的一个数n,如何判断其是否是素数呢?

最简单最直观的方法是试除法(下面的算法1、2、3),还有一种方法是Rabin-Miller算法。

  1. From 2 To n
    1. 思路:从2到n-1,做取模运算n mod ( i ),若运算结果均为 0 ,则 n 为素数
    2. 实现:
      public boolean isPrimeNumber(int n){
          for(int i = 2;i < n; i++){
              if(n%i==0)
                  return false;
          }
          return true;
      }
  2. From 2 To n?
    1. 思路:对上一个方法的优化,只要循环到 n? 就足以判断了
    2. 实现:
      public boolean isPrimeNumber(int n){
          int target = (int)Math.sqrt(n);
          for(int i= 2;i<target;i++)
              if(target%i==0)
                  return false;
          return true;
      }
  3. From Prime[min] To Prime[max]
    1. 思路:将 n? 之前的所有素数存到数组,在该素数数组内循环
    2. 实现:
      class Solution{
          int[] Prime = new int[Integer.MAX];
          Prime[0] = 2;
          count = 1;
          
          //与其说是检测是否为素数,本程序其实是从头开始建立素数数组,无法做到针对单一数字的离散判断,而且对于大数而言,空间代价较大
          public static boolean isPrime(int n){
              int target = (int)Math.sqrt(n);
              for(int i = 0;i<count;i++)
                  if(target%Prime[i]==0)
                      return false;
              return true;
          }
      }
  4. Rabin-Miller算法
    1. 思路:判断 n 是否为素数,首先要确保 n 是奇数。另外已知奇数总能写成 n = (2^r)*s+1,其中 s 也是奇数。Rabin-Miller算法是一种概率素数检测算法,该算法认为:只要奇数 n 能够满足①或者②(通过Rabin-Miller测试),那么他就是一个素数。【但事实是,有些合数也能通过Rabin-Miller测试,所以在实践时,往往会多做几次测试,也就是换个 a 多做几次①和②,如果每次都能通过测试,那么就说 n 是个素数,且正确率极高】
      1. 验算①:取随机整数 a ,a的取值范围是[1,n-1],a^s = 1 mod n
      2. 验算②:取随机整数 a ,a^s((2^j)*s) = -1 mod n ,其中0≤j<R.
    2. 实现:(未验证)
      //n是待测数字,s设定Rabin-Miller测试次数
      public boolean isPrime(int n, int s){
          for(int  i=0;i<s;i++){
              int a = rand()*(n-2)/RAND_MAX+1;
              //只要有一次没有通过Rabin-Miller测试,那么 n 就不是素数
              if(RabinMiller(a,n))
                  return false;
          }
          return true;
      }
      
      //一次Rabin-Miller测试实现
      public boolean RabinMiller(int a,int n){
          long i,d=1,x;
          for(i = (int)Math.ceil(Math.log((double)n-1)/Math.log(2.0))-1; i>=0; i--){
              x = d;
              d = (d*d)%n;
              if( 1==d && x!=1 && x!=n-1)
                  return true;
              if((n-1)&(1<0))
                  d = (d*a)%n;
          }
          return d!=1;
      }

 

以上是关于求素数的高效实现的主要内容,如果未能解决你的问题,请参考以下文章

求C语言中 判断素数的 代码!!!!!

HDu 2138 How many prime numbers 高效Miller素数測试

C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊

具有素数列表的高效素数分解算法

求50-100内的素数(java)

用C++求50~100内的素数,具体问题如下