精华内容
下载资源
问答
  • python求素数算法There are various methods through which we can calculate prime numbers upto n. 我们可以通过多种方法来计算最大为n的素数 。 1) General Method 1)一般方法 In this method, we usually ...

    python求素数算法

    There are various methods through which we can calculate prime numbers upto n.

    我们可以通过多种方法来计算最大为n的素数

    1) General Method

    1)一般方法

    In this method, we usually run two for loops in which the First one is used to increase the number and the second one is used to check whether the number is prime or not. Second loop runs from 2 to ( n / 2 + 1 ) ( for better performance).

    在这种方法中,我们通常运行两个for循环,其中第一个循环用于增加数字,第二个循环用于检查数字是否为质数。 第二个循环从2到(n / 2 +1)运行(以获得更好的性能)。

    Note: This is the least efficient method (one should not use this if efficiency is required.)

    注意:这是效率最低的方法(如果需要效率,则不应使用此方法。)

    2) Square-Root Method

    2)平方根法

    In this method, two loops run first one is to increase the number and the second one is to check whether the number is prime or not. The second loop runs from 2 to square root (number) (a number which is to be check), that’s why the run length of second for loop is relatively small, that’s why it’s efficient than the naïve approach.

    在此方法中,运行两个循环,第一个循环是增加数字,第二个循环是检查数字是否为质数。 第二个循环从2到平方根(数字)(要检查的数字),这就是为什么第二个for循环的运行长度相对较小的原因,这就是为什么它比幼稚的方法有效的原因。

    3) Sieve of Eratosthenes

    3)Eratosthenes筛

    This is the best and most efficient method to calculate the prime numbers upto n.

    这是计算最高达n的素数的最佳和最有效的方法。

    Algorithm for Sieve of Eratosthenes:

    Eratosthenes筛分算法:

    1. Let A be an array from 2 to n.

      设A为2到n的数组。

      Set all the values to

      将所有值设置为

      True (we are considering every number to be Prime)

      正确 (我们认为每个数字都是素数)

    2. For loop from p == 2 (smallest prime number)

      从p == 2开始的循环(最小质数)

    3. For loop from p2 to n

      从p 2到n的循环

      Mark all the multiples of

      标记所有的倍数

      p as False and increase the value of p to the next prime number

      数p作为假和增加p值到下一个素数

    4. End of second FOR loop

      第二个FOR循环结束

    5. End of first FOR loop

      第一个FOR循环结束

    At the end of both the for loops, all the values that are marked as TRUE are primes and all the composite numbers are marked as FALSE in step 3.

    在两个for循环的末尾,在步骤3中,所有标记为TRUE的值均为质数,所有复合数字均标记为FALSE。

    Time complexity : O(n*log(log(n)))

    时间复杂度:O(n * log(log(n)))

    Note: Performance of General Method and SquareRoot Method can be increased a little bit if we check only ODD numbers because instead of 2 no even number is prime.

    注意:如果只检查ODD数,则通用方法和SquareRoot方法的性能可以提高一点,因为不是2的偶数不是素数。

    Example:

    例:

    from time import time
    from math import sqrt
    
    def general_approach(n):
        '''
        Generates all the prime numbers from 2 to n - 1.
        n - 1 is the largest potential prime considered.
        '''
        start = time()
        count = 0
        for i in range(2, n):
            flag = 0
            x = i // 2 + 1
            for j in range(2, x):
                if i % j == 0:
                    flag = 1
                    break
            if flag == 0:
                count += 1
        stop = time()
        print("Count =", count, "Elapsed time:", stop - start, "seconds")
    
    def count_primes_by_sqrt_method(n):
        '''
        Generates all the prime numbers from 2 to n - 1.
        n - 1 is the largest potential prime considered.
        '''
        start = time()
        count = 0
        for val in range(2, n):
            root = round(sqrt(val)) + 1
            for trial_factor in range(2, root):
                if val % trial_factor == 0:
                    break
            else:
                count += 1
        stop = time()
        print("Count =", count, "Elapsed time:", stop - start, "seconds")
    
    def seive(n):
        '''
        Generates all the prime numbers from 2 to n - 1.
        n - 1 is the largest potential prime considered.
        Algorithm originally developed by Eratosthenes.
        '''
        start = time()
        # Each position in the Boolean list indicates
        # if the number of that position is not prime:
        # false means "prime," and true means "composite."
        # Initially all numbers are prime until proven otherwise
        nonprimes = n * [False]
        count = 0
        nonprimes[0] = nonprimes[1] = True
        for i in range(2, n):
            if not nonprimes[i]:
                count += 1
                for j in range(2*i, n, i):
                    nonprimes[j] = True
        stop = time()
        print("Count =", count, "Elapsed time:", stop - start, "seconds")
    
        # Time complexity : O(n*log(log(n)))
    
    def main():
        print("For N == 200000\n")
        print('Sieve of Eratosthenes Method')
        seive(200000)
        print('\nSquare Root Method')
        count_primes_by_sqrt_method(200000)
        print('\nGeneral Approach')
        general_approach(200000)
    
    main()
    
    

    Output

    输出量

    For N == 200000
    
    Sieve of Eratosthenes Method
    Count = 17984 Elapsed time: 0.050385475158691406 seconds
    
    Square Root Method
    Count = 17984 Elapsed time: 0.9392056465148926 seconds
    
    General Approach
    Count = 17984 Elapsed time: 101.83296346664429 seconds
    
    
    

    翻译自: https://www.includehelp.com/python/calculate-prime-numbers-using-different-algorithms-upto-n-terms.aspx

    python求素数算法

    展开全文
  • 最快求素数算法100000000以下所有素数0.3秒 , 在10000000以下的数中找到664579个素数,耗时53毫秒
  • 求质数素数算法,及算法优化

    千次阅读 多人点赞 2019-08-11 10:47:29
    质数素数):只能被1和其本身整除的数字(其中1和0不属于质数) 接下来我们用多种方法1000以内(包含1000)的质数数量,并且统计每种方法的循环次数 (如果只想知道速度快的方法可以直接看方法五) 方法一: 循环...

    质数(素数):只能被1和其本身整除的数字(其中1和0不属于质数)

    接下来我们用多种方法求1000以内(包含1000)的质数数量,并且统计每种方法的循环次数
    (如果只想知道速度快的方法可以直接看方法五)

    方法一:

    循环遍历所有情况

    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    for(int i=2;i<=1000;i++) {
        int flag = 0;//用作标记,如果是质数就为0,不是质数就为1
        for(int j=2;j<i;j++){
            count1++;
            if(i % j == 0 ){
                flag = 1;//不是质数,改为1
            }
        }
        if(flag == 0){
            count2++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    此时总循环次数为498501次
    质数个数有168个

    方法二

    改进点: 当一个数第一次被比自己小的数(不包含1)整除成功后,我们就可以立刻判断出这个数不是质数,所以我们使用break跳出循环,结束对这个数接下来的判断

    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    for(int i=2;i<=1000;i++) {
        int flag = 0;//用作标记,如果是质数就为0,不是质数就为1
        for(int j=2;j<i;j++){
            count1++;
            if(i % j == 0 ){
                flag = 1;//不是质数,改为1
                break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断
            }
        }
        if(flag == 0){
            count2++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    此时总循环次数为78022次
    质数个数有168个

    方法三

    改进点: 如果存在数字1能被数字2整除,那么一定存在这样一个小于等于数字1算术平方根的数字2(数学定理),所以一个数字在2~本身算术平方根这个数字区间内没有遇到能够被整除的数字,那么这个数就不是质数
      简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。

    注释掉的部分可以进一步提高计算速度,但提高不是非常大

    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    for(int i=2;i<=1000;i++) {
        int flag = 0;//用作标记,如果是质数就为0,不是质数就为1
        //if(Math.sqrt(i)!=(int)Math.sqrt(i)){
             for (int j = 2; j <= Math.sqrt(i); j++) {//j改为小于i的平方根
                 count2++;
                 if (i % j == 0) {
                     flag = 1;//不是质数,改为1
                     break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断
                 }
             }
         //}else {
         //    count2++;
         //}
        if (flag == 0) {
            count1++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    此时总循环次数为5288次
    质数个数有168个

    方法四

    改进点: 如果数字1取余数字2不等于0,那么数字一取余数字2的倍数一定也不为0。
    例如:7%2!=0那么我们没必要再去算7%4和7%6,因为4=22,6=32
    所以,我们只需要判断一个数是否能被小于他的质数除尽即可
    在这里我们将已经算出来为的质数存到一个数组中,后续的%只需对该数组中小于这个数本身平方根的数字进行

    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    int re[] =new int[500];//定义一个数组,用于储存质数
    re[0] = 2;
    int k = 0;
    for(int i=2;i<=1000;i++) {
        int flag = 0;//用作标记,如果是质数就为0,不是质数就为1
        for(int j=0;j<=k;j++){
            count2++;
            if(re[j]>Math.sqrt(i)){//只去小于等于该数字本身平方根的数字
                break;
            }
            if(i % re[j] == 0 ){//只对质数取余
                flag = 1;//不是质数,改为1
                break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断
            }
        }
        if (flag == 0) {
            re[++k] = i;
            count1++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    此时总循环次数为3467次
    质数个数有168个

    方法五

    boolean prime[] = new boolean[1001];
    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    for(int i=2;i<1000;i++){
        prime[i] = true;
    }
    for(int i=2;i<=1000;i++){
        if(prime[i]){
            for(int j=i+i;j<1000;j+=i){
                count2++;
                prime[j] = false;
            }
        }
    }
    for(int i=0;i<=1000;i++){
        if(prime[i] == true){
            count1++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    此时总循环次数为1956次
    质数个数有168个

    讲解: 利用了筛法,首先,2是公认最小的质数,所以,先把所有2的倍数去掉;然后剩下的那些大于2的数里面,最小的是3,所以3也是质数;然后把所有3的倍数都去掉,剩下的那些大于3的数里面,最小的是5,所以5也是质数……
      上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。维基百科上有一张很形象的动画,能直观地体现出筛法的工作过程。
    在这里插入图片描述

    问题延伸

    现在是让你求1000以内的素数,我们可以写死让i<=1000,但如果题目改为让你按从小到大的顺序,输出1000个质数该怎么办呢?第1000个质数的范围在哪里呢?
    如果我们使用上面的方法四可以这样写

    int count1 = 0;//质数个数
    int count2 = 0;//循环次数
    int re[] =new int[1001];//定义一个数组,用于储存质数
    re[0] = 2;
    int k = 0;
    for(int i=2;;i++) {
    	if(count1==1000){
    		break;
    	}
        int flag = 0;//用作标记,如果是质数就为0,不是质数就为1
        for(int j=0;j<=k;j++){
            count2++;
            if(re[j]>Math.sqrt(i)){//只去小于等于该数字本身平方根的数字
                break;
            }
            if(i % re[j] == 0 ){//只对质数取余
                flag = 1;//不是质数,改为1
                break;//既然已经知道这个数不是质数,那么就可以结束对这个数字的判断
            }
        }
        if (flag == 0) {
            re[++k] = i;
            count1++;
        }
    }
    System.out.println(count1);
    System.out.println(count2);
    

    但是我们知道方法四方法五要慢很多,但方法五中我们是提前定好了boolean prime[] = new boolean[1001];,第一千个质数我们应该将prime[]的大小定位多少呢?

    这就涉及到了我们的数学知识, 数学家找到了一些公式,用来估计某个范围内的素数,大概有几个。在这些公式中,最简洁的就是 x/ln(x),公式中的 ln 表示自然对数(估计很多同学已经忘了啥叫自然对数)。假设要估计1,000,000以内有多少质数,用该公式算出是72,382个,而实际有78,498个,误差约8个百分点。该公式的特点是:估算的范围越大,偏差率越小。
      有了素数定理,就可以根据要打印的质数个数,反推出这些质数分布在多大的范围内。因为这个质数分布公式有一定的误差(通常小于15%)。为了保险起见,把反推出的素数分布范围再稍微扩大15%,应该就足够了。

    空间优化

    看到这你因为这已经是最优的解法了吗?不,现在我们只优化了时间,还没有优化空间。
    有些程序猿会想出按位(bit)存储的思路。
      以Java为例。一个boolean占用4字节内存(boolean类型占了单独使用是4个字节,在数组中又是1个字节)。而1个字节有8个比特,每个比特可以表示0或1。所以,当你使用按位存储的方式,一个字节可以拿来当8个布尔型使用。所以,构造一个定长的byte数组,数组的每个byte存储8个布尔值。空间性能相比直接定义boolean,提高8倍(对于Java而言)。

    最后总结

    关于代码优化这件事,我认为没有最优,只有更优,科技永远不会停下前进的脚步

    努力吧,少年!

    展开全文
  • 完整的 python 求素数算法 可以限定运行次数 可以中断保存
  • c代码-求素数算法

    2021-07-16 14:36:52
    c代码-求素数算法
  • c++ 求素数优化算法

    2018-09-12 21:30:31
    新手我热爱算法,第一次由个人琢磨出来的优化任意两个数之间的素数算法,谢谢。我个人觉得,他似乎可以减少时间复杂度
  • java求素数算法

    千次阅读 2015-02-03 22:31:08
    100内的素数: public void a() { for (int i = 2; i ; i++) { int temp = (int) Math.sqrt(i); // 我把那个aqrt单独提出来,这样速度稍微快一点,虽然在100内变化不大,但如果是10000000内的素
    求100内的素数:
    
       public void a() {  
                for (int i = 2; i <= 100; i++) {  
                    int temp = (int) Math.sqrt(i);  
                    // 我把那个aqrt单独提出来,这样速度稍微快一点,虽然在100内变化不大,但如果是10000000内的素数呢?  
                    if (i <= 3) {  
                        System.out.println(i + " is a prime");  
                    } else {  
                        for (int j = 2; j <= temp; j++) {// 把Math.sqrt(i)转换为int类形  
                            if (i % j == 0) {  
                                break;  
                            }  
                            if (j >= temp) {  
                                System.out.println(i + " is a prime");  
                            }  
                        }  
          
                    }  
                }  
            }  

    (二)求n-m间的素数
      public void sushu(int n ,int m){  
                for (int i = n; i < m; i++) {  
                    int temp = (int)Math.sqrt(i);  
                    if(i<=3){  
                        System.out.println(i);  
                    }  
                    for (int j = 2; j <= temp; j++) {  
                        if(i%j==0){  
                            break;  
                        }  
                        if(j>=temp){  
                            System.out.println(i);  
                        }  
                    }  
                }  
            } 
    


    展开全文
  • 求素数算法

    2020-04-18 00:56:10
    问题:输入一个正整数n,输出不大于n的所有素数质数) 1.循环法 素数是除了1和它本身外没有其他因子的数,因此用n除以2~n-1的所有整数,如果有一个数能够整除,则n不是素数(是合数) 为了循环简单,可以跳过一些...

    问题:输入一个正整数n,输出不大于n的所有素数(质数)

    1.循环法

    素数是除了1和它本身外没有其他因子的数,因此用n除以2~n-1的所有整数,如果有一个数能够整除,则n不是素数(是合数)

    为了循环简单,可以跳过一些不必要的判断:

    • 2是素数,可以从3开始循环
    • 只需要判断到√n,由于n=√n*√n,n的因数除了√n,其他都是成对存在的,且必定一个大于√n一个小于√n,假设n不是质数,有个因数大于√n(不是n本身),则n必定有一个与之对应的小于√n的因数
    • 除了2以外,没有是偶数的质数,因此循环步长设为2
    #include<stdio.h>
    int main()
    {
        int n;
        scanf("%d",&n);
        printf("2\n");
        for(int i=3;i<=n;i+=2)
        {
            for(int m=3;m<i;m+=2)
            {
                if(i%m==0 || m*m>i)
                    break; 
            }
            if(m*m>i)
                printf("%d\n",i);
        }
    
        return 0;
    }
    

    2.埃氏筛

    思想是把不大于√n的质数的倍数全部去除,剩下的就是质数

    从 2开始,把 2的倍数(不包括本身)标记为合数,然后向后枚举,查到一个未标记为合数的,就把它的倍数(不包括本身)标记为合数。以此类推,筛到 n 为止。

    #include<stdio.h>
    #define MAX 100
    int s;
    int a[MAX];
    void prime()
    {
        s=1;
        for(int i=0;i<=MAX;i++)
            a[i]=1;
        a[0]=a[1]=0;
        for(int i=2;i<=MAX;i++)
        {
            if(a[i])
                a[s++]=i;
            for(int j=i*2;j<=MAX;j+=i)
                a[j]=0;
        }
    }
    int main()
    {
        prime();
        for(int i=1;i<s;i++)
            printf("%d\n",a[i]);
        return 0;
    }
    

    由于埃氏筛会把数重复标记,如 24 被2,3,4三个数标记,导致效率降低,时间复杂度是O(n log logn),对于较大的输入可能会超时

    引入优化算法欧拉筛
    (还没看欧拉筛的算法,先挖个坑…)

    展开全文
  • Python求素数算法

    千次阅读 2017-03-06 15:57:08
    i = 2; while(i  j = 2;  while (j  if not (i%j):break  j = j +1  if(j > i /j):print (i," 是素数")  i = i+1 print ("Good bye!")
  • 素数算法有很多种,现在主要讲两种算法及其改进版本的复杂度分析,解释性能提升的幅度。...现以100000内素数为例,两种算法分别是: 1.基础思路是去掉偶数,包括取模的范围,代码如下: print(2...
  • 求素数的优化算法

    2019-11-03 21:19:54
    题目:1~N范围中的素数。k为当前数值,j为被除数 素数:一个大于1的自然数中,除了1和本身外无法整除其余数的数值。 对于素数,可以忽略双数部分,因为均能被2整除,2也是素数做特殊情况,直接输出,即除去双数的...
  • 文章目录Python 如何素数、质数素数、质数(重点)方法一:枚举方法二:厄拉多塞筛法【埃氏筛】方法三:线性筛相关博客 素数、质数(重点) 先明白什么是素数 质数,英文名:Prime number,又称为素数,指的是值大于1...
  • 1.除了2以外所有2的倍数都不是素数 2.如果num能被2~m-1之间任意一个整数整除,它的两个因子一定有一个小于等于根号num,另一个大于等于根号num,所以当根号num之前没有找到因数,在它之后也不会有因数 #include <...
  • c++求素数算法 简洁

    2009-04-20 18:48:55
    很简单的 精炼的算法 代码很短 容易理解
  • 筛选法求素数算法详解

    千次阅读 2014-09-16 19:16:21
    原文地址:筛选法求素数算法详解作者:在路上   #include using namespace std; const int MAXV = 10000; //素数表范围 bool flag[MAXV+1]; //标志一个数是否为素数 int prime[MAXV+1]; //素数表,下标从0...
  • 求素数的高效算法 Prime numbers are natural numbers greater than 1 that have only two divisors (the number itself and 1). By “divisible” we mean dividend % divisor = 0 (% indicates MODULAR....
  • 前端JS算法素数

    千次阅读 2020-11-25 18:01:02
    在看代码之前,我们先梳理一下逻辑,什么是素数,百度百科上写到,素数又称质数质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。那我们可以理解为只能被1和它本身整除的数就是素数。 逻辑...
  • 求质数算法

    2018-12-13 15:45:30
    利用质数的倍数不是质数来实现 int range//范围 boolean[] isPrime//初始化为true,isPrime[1]=false; int n=sqrt(range) for(int i=1;i&lt;n;i++) {  if(isPrime[i])  {  for(int j=2*i;j&lt;...
  • python求质数的3种方法

    2020-09-20 02:16:43
    主要为大家详细介绍了python求质数的多种方法,多种方法求质数的实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 求素数算法(C语言)

    千次阅读 2016-09-07 12:42:51
    以下是用C语言一定范围内的素数。#include #include int imax(int,int); void main(void) { int m,k,i; for(m=101;m;m+=2){ k=(int)sqrt((double) m); for(i=2;i;i++){
  • 求素数质数算法 如果一个正整数只有两个因子,1和p,则p为素数 1、根据概念判断 bool isPrime(int n) { if(n < 2) return false; for(int i = 2; i < n; ++i) if(n%i == 0) return false; r...
  • 高效质数判断算法及其JS实现

    千次阅读 2017-01-24 00:02:32
    高效质数判断算法及其JS实现 高效质数判断算法及其JS实现 理论基础 质数的定义 质数与合数 最小质因子的取值范围 质数的分布 理论基础 1.质数的定义 大于1的正整数中,只能被1和自身整除的数称为...
  • 求素数算法简化

    千次阅读 2019-04-27 02:01:46
    谈起求素数的问题,可能许多人嗤之以鼻,认为是编程学习最简单最基础的一部分,可是,真的是这样吗? 试问:当一个数足够大,或者对该算法的时间有严格的限制时,还是如此简单吗?正文 乍眼一看,第一反应应该是这样...
  • 求素数算法-Java

    万次阅读 2016-07-19 15:50:12
    例如1000以内的素数: 方法一:定义 素数:除了1和它本身以外不再被其他的除数整数。  public void printPrime(){  for(int i=2; i&lt;1000; i++)  {  if(2==i || 3==i){  System.out.print(i+"...
  • Java求质数的几种常用算法分析

    千次阅读 2019-03-25 14:22:37
    本文实例讲述了Java求质数的几种常用算法。分享给大家供大家参考,具体如下: 1、根据质数的定义 质数定义:只能被1或者自身整除的自然数(不包括1),称为质数。 利用它的定义可以循环判断该数除以比它小的每个...
  • 求素数算法

    千次阅读 2013-11-05 22:56:12
     挨个循环用n除以2到n-1的所有整数,如果期间有一个能整除,那么n是合数(不是素数)。 2. 利用一个定理:如果一个数是合数,那么它的最小质因数肯定小于等于他的平方根。反证法:  设a = bq,因为a是合数,则b和q...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 74,864
精华内容 29,945
关键字:

求质数的算法