zoukankan      html  css  js  c++  java
  • 素数判断算法

    • 质数只能被1和自己本身整除的数
    • 如:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97...

    方法1:时间复杂度O(n)

    • 最直观的方法,根据定义,因为质数除了1和本身之外没有其他约数,所以判断n是否为质数,根据定义直接判断从2到n-1是否存在n的约数即可
      function  isPrime(num){
          if(num ==2 || num==3)
                  return true;
          for (var i = 2;i <= n-1;i++) {
            if(num % i ==0){
              return false;
            }
          }
          return true;
        }
    

    方法2:时间复杂度O(logN)

    • 上述判断方法,明显存在效率极低的问题。对于每个数n,其实并不需要从2判断到n-1
    • 我们知道,一个数若可以进行因数分解,那么分解时得到的两个数,一定是一个小于等于sqrt(n)和一个大于等于sqrt(n)
    • 据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数
      12
      1×12=12
      2×6=12
      3×4=12
      4×3=12
    • 能被2整除的数一定不是素数,所以不用被4、6整除,这样能减少n/2次执行次数
    • 能被3整除的数一定不是素数,所以不用被6、9整除,这样能继续减少执行次数
      function  isPrime(num){      
          if(num ==2|| num==3 )
            return true;
          var temp = parseInt(Math.sqrt(num));
          for (var i = 2;i <= temp;i++) {
            if(num % i ==0){
              return false;
            }
          }
          return true;
        }
    

    方法3:时间复杂度

    • 2x,3x,5x肯定不是质数
    • 此时判断质数可以2个为单元快进,即在循环中i++步长加大为2,加快判断速度
    function isPrime(num){
      if(num ==2 || num==3)
            return true;
      if(num % 2 == 0 || num % 3 == 0 || num % 5 == 0)
        return false;				
      var temp = parseInt(Math.sqrt(num));
      for (var i = 7;i <= temp;i=i+2) {
        if(num % i == 0){
          return false;
        }
      }
      return true;
    }		
    

    方法4:时间复杂度

    • 证明:令x≥1,将大于等于5的自然数表示如下:
    • ······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······
    • 可以看到,6的倍数两侧之外的数为6x+2,6x+3,6x+4,由于2(3x+1),3(2x+1),2(3x+2),所以它们一定不是素数,再加上6x本身也不是素数
      • 所以在6的倍数两侧的一定是质数,及:if(num %6!= 1&&num %6!= 5) return false ;
      • 在6的倍数相邻两侧并不是一定就是质数
    • 此时判断质数可以6个为单元快进,即在循环中i++步长加大为6,加快判断速度
      • 原因是,假如要判定的数为n,则n必定是6x-1或6x+1的形式,对于循环中6i-1,6i,6i+1,6i+2,6i+3,6i+4,其中如果n能被6i,6i+2,6i+4整除,则n至少得是一个偶数,但是6x-1或6x+1的形式明显是一个奇数,故不成立
      • 另外,如果n能被6i+3整除,则n至少能被3整除,但是6x能被3整除,故6x-1或6x+1(即n)不可能被3整除,故不成立。
      • 综上,循环中只需要考虑6i-1和6i+1的情况,即循环的步长可以定为6,每次判断循环变量k和k+2的情况即可,理论上讲整体速度应该会是方法(2)的3倍
    function isPrime(num){
      //两个较小数
      if(num == 2 || num == 3 )
          return true ;
      //不在6的倍数两侧的一定不是质数
      if(num%6 != 1 && num%6 != 5){
          return false ;
      }    
      var tmp =Math.sqrt(num);
      //在6的倍数两侧的也可能不是质数
      for(var i = 5;i <= tmp; i+=6 )
          if(num%i == 0 || num%(i+2) == 0)
              return false ;                 
      return true;
    }
    

    ❤️有则改之,无则加勉。如有错误、建议、疑问,评论或联系飞沙QQ:2602629646
    ❤️本文来自作者:MrFlySand,转载请注明原文链接:https://www.cnblogs.com/MrFlySand/p/13673922.html

  • 相关阅读:
    转载一篇不错的Mac上安装Apache和多版本PHP的文章
    Mac 上配置tomcat 及可能碰到的问题。
    iOS通知中心 NSNotificationCenter详解
    字符缓冲区读取文件BufferedReader
    BufferedWriter—newLine
    缓冲流复制文件与基本流复制文件比较
    BufferedOutputStream缓冲流
    properties集合
    JDK7,JDK9流中异常的处理
    try-catch-finally处理流中的异常
  • 原文地址:https://www.cnblogs.com/MrFlySand/p/13673922.html
Copyright © 2011-2022 走看看