得到质数序列 如何判断一个数是否为质数&得到质数序列

如何判断一个数是否为质数&得到质数序列

数的定义是:只能被1和本身整除而不能被其他数整除。(好了好了,这个初中生都知道……)

断一个数n是不是素数,最靠谱的方法就是用所有小于n的数来一个一个检测是不是能被n整除。不过稍微聪明一点的办法是只要用小于k = floor(sqrt(n))//取不大于n的平方根的最大整数的数来检测就可以了。原因如下:k^2 < n,而(k+1)^2 > n,假设是 k(k+1) = n,但是这个时候只要用k检测过就可以判断是不是为质数了,不需要用k+1。同样如果是k(k+2),k(k+3)一样的。

函数代码如下:

public static boolean isPrime(int a) {  
        if (a <= 2) 
            return false;  
        else {  
            int max =  (int) Math.floor( Math.sqrt(n)); 
            for (int i = 2; i <= max; i++) 
                if (a % i == 0) // 若能被整除,则说明不是素数,返回false  
                    return false;   
        }  
        return true;  
    }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上这种方法对于不是很大的数字来说没有问题,但如果是一个很大的数字,计算时间就太长了。比如加密解密程序中,往往需要一个100位的大数,对于大数判断是否为素数,推荐Miller Rabin算法。这个算法的核心思想是:如果p是素数,x是小于p的正整数,且x^2 mod p = 1,那么要么x=1,要么x=p-1。 有兴趣的话建议自行Google,会有相关算法解释,因为还是比较复杂的,涉及到费马小定理、快速幂模算法之类的,加上博主本人数学也没有好到哪去,所以先不说咯~


到一个小于n的所有质数序列,常用的方法是埃拉托色尼检测法(Eratosthenes)。其原理是:从第一个最小的数k开始作为因子来检测,从k^2开始进行判断,这是因为,k(k-1)、k(k-2)、……、2k一定都经过了之前数字的检测!并且每次被检测数字的跨度是k。k^2之后的数字中可以被其整除的就不是素数,剔除。检测到 floor(sqrt(n))就可以停止,理由同上,因为每次要从k^2开始检测。所以循环结束的条件是k^2 > n

个例子:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

第一次用2来测试,从4开始检测,结果如下:

2 3 5 7 9 11 13 15 17

第二次用3来测试,从9开始检测,结果如下:

2 3 5 7 11 13 17

此时应该用5来测试,但是由于5^2 = 25 > 17,所以结束。

下面附上函数代码块的Java实现(用了ArrayList,便于删除):

//产生不大于n的连续质数序列
    public static ArrayList<Integer>  eratosthenes( int n){
        ArrayList<Integer> array = new ArrayList<Integer>();
        for(int i = 2; i < n; i ++)
            array.add(i);
        //最多只要计算到n的平方根即可,因为2p,....,(p-1)p都已经在之前测试过了
        int max =  (int) Math.floor( Math.sqrt(n)); 
        for(int p= 2;  p < max; p ++){
            Integer j = p * p;
            while( j < n ){
                if( j % p == 0)
                    array.remove( j );
                j = j +p; 
            }
        }
        return array;
    }
  • 1
  • 2
  • 3有时候我们不光去需要判断这个数是否为质数,还要判断当我们给定一个数值之后在这个数值内有多少质数
  • 首先给定一个vector数组,并且都赋值为1,意味着现在把数组里的所有数都当作质数,然后我们从2开始取,那么凡是2的倍数,并且在给定的数值内部              
  • 那么就把它置为0;之后在检查下一个是否为1,也就是看看下一个是否是质数,不是就continue,
  • if(vec[i]==0)
  • continue;
  • 例如下一个是3,那么3的倍数,当然有交叉的,自然
  • 也要考虑进去比如
  • if(vec[i*j]==0)continue;
  • 并且i*j<所要表达的数,从而经过循环把所有的质数都找出来
  • 想找到几对质数的和等于特定值ACnum
  • for(int i=0;i<n/2;i++)
  • {
  • if(vec[i]&&vec[ACnum-i])count++;
  • 意思是取出第一个质数,然后看ACnum-这个质数看看是否也是质数,如果是的话,就加入

  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

以上 欢迎指正错误 共同学习
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Chely_Yi/article/details/52507693
文章标签:  算法-质数测试
个人分类:  算法
27岁沈阳妹子竟悟出股市投资铁律,爆赚成网红利云 · 顶新
沈阳股民福利:A股或将迎一波大行情,这5类股获将领涨!!佳亿道荘 · 顶新

猜你喜欢

转载自blog.csdn.net/qq_40086556/article/details/80320105