精华内容
下载资源
问答
  • 革命性素数算法:计算1亿内素数只要1.6秒 算法基本跟之前发的C#版相同(http://download.csdn.net/source/690005内有算法描述),由我的朋友杨力2年前设计,时间复杂O(n)。我对其进行了革命性的数据结构改进,空间...
  • 最快素数算法,求100000000以下所有素数0.3秒 , 在10000000以下的数中找到664579个素数,耗时53毫秒
  • 复查素数测试算法并测试其性能,以找出最快算法
  • 目前已知的一种快速的求素数算法就是Sieve of Atkin 算法
    目前已知的一种最快速的求素数的算法就是Sieve of Atkin 算法!
    展开全文
  • 首先涉及到判断一个给定的数n是否为素数,其简单的算法是,依次判断所有大于1且小于n的整数中是否存在能被n整除的数i,若存在则n不是素数,不存在则n为素数。代码实现如下: //算法1 int isPrimeNumber(long n) { ...

    前m个素数是指从2开始的m个素数,比如前3个素数是:2,3,5;前10个素数是:2,3,5,7,11,13,17,19,23,29。
    要找出前m个素数,很容易想到的算法是从2开始依次判断每一个整数是否是素数,直到找到m个素数。首先涉及到判断一个给定的数n是否为素数,其最简单的算法是,依次判断所有大于1且小于n的整数中是否存在能被n整除的数i,若存在则n不是素数,不存在则n为素数。代码实现如下:

    //算法1
    int isPrimeNumber(long n)
    {
    	for(int i = 2; i < n; i++)
    	{
    		if(n % i == 0)
    			return 0;  //n不是素数
    	}
    	return 1;  //n是素数
    }
    

    该算法最简单明了,但有很大的缺点,判断次数多,冗余操作多,时间复杂度为O(n)。

    实际上,算法1中n除以i得到的商小于i后,依然没有出现整除,则之后的整数已无需判断,就可以判定n为素数。因此对该算法进行一个简单的优化,将for(int i = 2; i < n; i++)改为for(int i = 2; i <= n/i; i++),所得到的新算法记为算法2,其冗余的判断整除的操作减少很多,时间复杂度减少到O(√n)。

    但是该算法依然存在冗余判断整除操作,例如n已经无法整除2和3,那么显然也无法整除6,但该算法依然会对6进行整除判断。若将算法中的这类冗余操作完全去除,则运算速度将会进一步加快。那么有没有一种算法能做到没有冗余呢?

    我们已知在数学上判断素数的方法:试除法,用从2开始的各个质数依次去除n,如果存在某一个质数整除,那么n不是质数;若不能整除,一直尝试到商小于除数,那么n是一个质数。这个方法没有冗余判断操作。

    在打印前m个素数的算法中,可以使用一个数组来记录已经找到的质数。前几个素数已经为人们所熟知,无需再进行计算,因此可以把它们提前记录在这个数组中,比如可以将前8个素数2,3,5,7,11,13,17,19预先填入数组,后面找到的其他素数依次填入其中。将该算法记为算法3。以算法3为基础,得到打印前m个素数的C代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    
    #define MAX_SIZE  10000   //最多记录的素数个数
    
    long primeNumberArray[MAX_SIZE] = {2, 3, 5, 7, 11, 13, 17, 19}; 
    //初始化数组,填入前8个熟知的素数
    int  currentPrimeNumber = 8;  //记录数组中已有的素数个数
    
    //判定一个给定的数n是否为素数,若是返回1,不是返回0,出错返回-1
    int isPrimeNumber(long n)
    {
    	long index = 0;
        for ( index = 0; index < currentPrimeNumber; index++)
    	{
    		if ( 0 == n % primeNumberArray[index] )
                return 0;  //n不是素数
    		else if ( primeNumberArray[index] > (n/primeNumberArray[index]))	
    		    return 1;  //n是素数
    	} 
        return -1;
    }
    
    int main()
    {
        int m;
        int result = 0, i = 0;
        long currentNumber = 21; //要判断的数,数组记录到19,从21开始
    
    	printf("number of prime numbers to print: ");
    	scanf("%d", &m);
    	printf("\n");
       
        while (currentPrimeNumber < m)
    	{
    		result = isPrimeNumber(currentNumber);
    		if (1 == result) //找到一个新的素数,记录到数组中
            {
    			primeNumberArray[currentPrimeNumber] = currentNumber;
                currentPrimeNumber++;
    		}
            else if (-1 == result)
            {
    			printf("Fatal error occur!\n");
    		}
    		currentNumber += 2; //大于2的偶数均为和数,因此递增2
    	}
        
        //打印前m个素数
    	printf("Index     Prime Number\n");
        for (i = 0; i < m; i++)
    		printf("%10d %ld\n",i + 1, primeNumberArray[i]);
    
    	return 0;
    }
    
    

    为了验证这个无冗余算法的性能优势,我们在该程序中的while循环前后记录时间点,用以计算该程序耗时,以微秒为单位,更改后的main函数如下:

    int main()
    {
        int m;
        int result = 0, i = 0;
        long currentNumber = 21;
    	struct timeval start, end;
    	struct timezone tz;
        long timeelapse = 0;
    
    	printf("number of prime numbers to print: ");
    	scanf("%d", &m);
    	printf("\n");
    
        gettimeofday(&start, &tz);  //开始计时
        while (currentPrimeNumber < m)
    	{
    		result = isPrimeNumber(currentNumber);
    		if (1 == result)
            {
    			primeNumberArray[currentPrimeNumber] = currentNumber;
                currentPrimeNumber++;
    		}
            else if (-1 == result)
            {
    			printf("Fatal error occur!\n");
    		}
    		currentNumber += 2;
    	}
        gettimeofday(&end, &tz);  //结束计时
        
    	printf("Index     Prime Number\n");
        for (i = 0; i < m; i++)
        {
    		printf("%10d %ld\n",i + 1, primeNumberArray[i]);
    	}	
    	
    	//计算并打印耗时,单位微秒
        timeelapse = (end.tv_sec - start.tv_sec)*1000*1000 + end.tv_usec - start.tv_usec;
        printf("timeelaspe = %ld\n", timeelapse);
        
    	return 0;
    }
    
    

    在Ubuntu虚拟机上将函数isPrimeNumber(long n)依次替换为算法1,2和3,在打印前1000个、前5000个和前10000个素数时重复运行5次,观测时间耗费(微秒)取平均值,统计得到如下表格:

    打印个数 1000 5000 10000
    算法1 40589 1155341 4978551
    算法2 1583 23223 71557
    算法3 902 7133 17284

    根据统计结果可以明显看出,算法1耗时最长,没有实用性,算法3在所有情况下的用时最少,效率最高。当打印素数的个数逐渐增加时,算法3相对于算法2的优势越来越大。但是算法3的使用也有一定局限性,其能判定的最大整数不能超过数组中最后一个素数的平方,并且其需要保存所得到的素数列表,因此比前两个算法占用更多的内存空间。

    展开全文
  • 参见英文答案 >Fastest primality test3个我正在...我使用以下代码/算法来检查给定数字是否为素数.但这是非常缓慢的,如果一个数字可以说长10个数字需要很长时间.public boolean returnPrime(BigInteger testNumbe...

    参见英文答案 >

    Fastest primality test                                    3个

    我正在编写一个方法来检测BigInteger是否为素数.我使用以下代码/算法来检查给定数字是否为素数.但这是非常缓慢的,如果一个数字可以说长10个数字需要很长时间.

    public boolean returnPrime(BigInteger testNumber){

    int divisorCounter=1;

    BigInteger index,i ;

    for ( index= new BigInteger("2"); index.compareTo(testNumber) !=1; index=index.add(new BigInteger("1"))){

    System.out.println(index);

    for(i= new BigInteger("2"); i.compareTo(index) != 1; i=i.add(new BigInteger("1"))){

    if((testNumber.mod(i).equals(BigInteger.ZERO) )){

    divisorCounter++;

    }

    if(divisorCounter>2){

    return false;

    }

    }

    }

    return true;

    }

    是否有更好的算法可以使用BigInteger素数?我在Stackoverflow中找不到与此相关的问题.如果您遇到过这样的问题请告诉我,或者如果您对如何解决有任何想法,那么您的想法将受到高度赞赏.

    展开全文
  • 优化都没尝试过就说这个算法内存占用什么的。。。。。 不才还有个「210里面中检测48个可能位置的」,也就是说,从开始就排除2、3、5、7的倍数。大概能提升到4倍(略低于4倍)。原理和代码稍晚放出。

    填坑了。

    之前说到,2 和 3之后,所有质数都必须满足6 n ± 1这个条件。所以利用这原理,可以提升三倍性能。这公式怎么来的呢?

    首先我们知道,2以后的质数都必须是奇数,公式表达就是2n + 1,当然用2n - 1也行。

    我们要把能整除3的过滤掉。即 2n + 1 不能整除3。我们做适当转换:

    2n + 1 => 3n - n + 1

    可见,我们只要确保1 - n不能整除3就可以。

    令 n = 3 m + x,则有2 * (3m + x) + 1 => 6m + 2x + 1 ,x 的取值范围为 0 和 2。

    所以得到,6m + 1 或者 6m + 5,其中6m + 5 等同于 6m - 1,只是m取值范围不同。

    证明完毕。

    同样,当我们有了6n ± 1之后,怎么去除 5和7 的倍数呢?刚好就这么巧:

    6n ± 1 => 5n + n ± 1

    6n ± 1 => 7n - n ± 1

    懂了吧,剩下展开就行了。实测下,把3倍数过滤掉,用欧拉确实获得巨大的性能提升。

    再把5倍数过滤掉,还能提升一点。到再过滤7倍数的时候,优势就有点看不到了,原因是,5级过滤到7级过滤,计算总量是从8/30 降到 48/210,节约率相比原始来说才3.8%,收益不多。

    说好的代码呢?呃,上吧,F# 的代码。

    let getPrimers maxValue =

    let table = [|0uy; 2uy; 6uy; 8uy; 12uy; 18uy; 20uy; 26uy; 30uy; 32uy; 36uy; 42uy;

    48uy; 50uy; 56uy; 60uy; 62uy; 68uy; 72uy; 78uy; 86uy; 90uy; 92uy;

    96uy; 98uy; 102uy; 110uy; 116uy; 120uy; 126uy; 128uy; 132uy; 138uy;

    140uy; 146uy; 152uy; 156uy; 158uy; 162uy; 168uy; 170uy; 176uy; 180uy;

    182uy; 186uy; 188uy; 198uy; 200uy|]

    let check = Array.zeroCreate (maxValue + 1)

    let prime = Array.zeroCreate (maxValue / 210 * 48 + 48)

    prime.[0]

    prime.[1]

    prime.[2]

    prime.[3]

    let rec loop n count step =

    let i = n + int32 table.[step]

    if i <= maxValue then

    let count =

    if not check.[i] then

    prime.[count]

    count + 1

    else

    count

    let rec loopPrime j =

    if j < count then

    let comp = i * prime.[j]

    if comp <= maxValue then

    check.[comp] 0 then

    loopPrime (j + 1)

    loopPrime 4 // 把0 改为 4,这一步很重要,因为原理上杜绝了 2357倍数的检查, // 所以直接不用标注, 2000万数据测试下,节约了1/4时间 if step + 1 = table.Length then

    loop (n + 210) count 0

    else

    loop n count (step + 1)

    loop 11 4 0

    ===================================

    看完一圈,没有一个好打的。

    就抄个公式出来了事。那些所谓擅长数学的,怎么不知道2和3之后,所有质数都必须满足6 n ± 1这个条件?因为只有6 n ± 1才能避开2和3的倍数。 欧拉筛法改一下,速度一下子提到3倍了。即使你真的不懂,也该知道2之后,所有质数都是奇数吧?也能从原来提升两倍速度了。如果你想,数组也可以趁机把数组开小一点。优化都没尝试过就说这个算法内存占用什么的。。。。。

    不才还有个「210里面中检测48个可能位置的」,也就是说,从开始就排除2、3、5、7的倍数。大概能提升到4倍(略低于4倍)。原理和代码稍晚放出。

    展开全文
  • 此代码因该是线性时间复杂度,可能是最快的方式 在Windows下调试,时间计数器可能有问题,暂不解决 如有错误请指出 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <...
  • 今天在博文C语言初学者代码中的常见错误与瑕疵(5)看了一个关于... Kong更的发出接近它的素数答案,你将会获得一个意想不到的礼物。 例如:当屏幕出现22时,你的回答应是23;当屏幕出现8时,你的回答应是7; ...
  • 素数判定Miller_Rabin 算法详解 上次说好的要把素数判定和大数分解(见另一...首先相信有一些数学和编程经验的读者应该知道,简单直观简单的素数判定方法就是试除法。对于判断数n是否是素数,我们从2开始一直到sqrt
  • 这个算法能大大提高查找孪生素数的效率 以下是JS代码:有算法思想和详细注释 &lt;!DOCTYPE html&gt; &lt;html&gt;  &lt;head&gt;  &lt;meta charset="utf-8"&gt;  &...
  • 算法-素数表_埃氏筛选法问题概述1. 问题分析1.1 算法核心2. 解决方案3. 资源分享 问题概述 题目:素数表_埃氏筛选法 问题描述: 在很多算法题中都会涉及到素数的使用,因此如何快速高效地求素数是我们程序猿必不可...
  • 算法】普通方法和筛选法求素数

    千次阅读 2015-04-02 00:09:05
    下面首先介绍如何判断一个是不是素数,然后介绍用普通方法求n以内的素数,接着是筛选法求n以内的素数,最后是两种算法的运行时间比较判断一个数是不是素数算法思想:判断小于等于一个数的平方的所有大于1的整数...
  • 求出不大于n的素数个数的最快方法

    千次阅读 2019-01-21 11:12:50
    我修改了之前的算法,重新想了一个算法,效率大大提高了 以下是JS编码:有算法思想和很详细的注释 &lt;!DOCTYPE html&gt; &lt;html&gt;  &lt;head&gt;  &lt;meta charset="utf...
  • 直接的思路就是根据质数的定义来判定一个数是不是质数(即一个数不能被除1和它本身外的任何数整除),如果我们需要对所有的数都这样进行判断,那么当n非常非常大的时候,这种算法的时间开销就会非常大,大概为O(n^...
  • 查找指定范围的自然数的所有质数,实现起来并不难,但是哪种算法效率最高,速度最快才是重点,我列出几种算法: 1、将待判断的值与小于它而且不小于2的所有数求余数 public static List<Integer> getprimeV1...
  • 它包括可能的有效的基于树的排序算法,并表明可以通过以正确的方式对先前素数之间的差异进行排序来找到新素数。 不幸的是,事实证明,这种方法比尝试通过蛮力找到素数要慢得多。 因此,它只能用作排序算法的重...
  • 问题描述 形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要...
  • 素数

    2021-03-01 13:52:33
      这是没用的算法,时间复杂度太高:枚举nnn以内的每一个数,再用试除法判断该数是否为素数。 code //Maxn 为数组q的大小。 bool q[Maxn} bool check(int n) { for(int i = 0 ; i * i < n ; i ++) if(n %...
  • 已优化到 22 秒内,不知道世界最快算法在同样环境下运行速度是多少,下面贴出代码,C# using System; namespace prime { class Program { static void Main(string[] args) { DateTime dt = DateTime.Now;
  • 很好的算法,学习到啦,推荐一下
  • 筛选法求素数

    2019-10-08 07:11:31
    一、概念: ... 1)最初的素数比较暴力,也只是能判断一个数是不是素数或者求n以内的素数个数,用朴素的算法来写就是下面这样的 num = 0; for(i=2; i<=n; i++) { for(j=2; j<=sqrt(...
  • 素数判定Miller_Rabin

    2017-12-05 14:34:30
    素数判定Miller_Rabin 算法详解 ...首先相信有一些数学和编程经验的读者应该知道,简单直观简单的素数判定方法就是试除法。对于判断数n是否是素数,我们从2开始一直到sqrt(n)。如果找到一个因子则判断
  • Miller Rabbin素数测试

    2018-10-16 21:30:00
    ②MR算法开始 (1)传入两个参数一个是底数一个是n也就是幂数,如果n是一个合数那么可以判定,这个数一定不是素数 (2)然后开始寻找一个奇数的n去计算,如果最后满足a^d%n=1那么这个可能就是一个素数,然后再判断k=n-1...
  • 素数的四种判断方法、实现及比较

    万次阅读 多人点赞 2019-05-26 11:52:40
    目录定义算法1)直观判断法2)直观判断法改进(2种)3)已知最快算法实现C++python 定义 约数只有1和本身的整数称为质数,或称素数。 计算机或者相关专业,基本上大一新生开始学编程都会接触的一个问题就是判断...
  • 小费马定理:如果n是素数,则(a ^ (n - 1)) % n恒等于1。 快速模取幂 米勒-拉宾算法就是结合上面两种,通过不断判断fmod(a, n - 1, n)的值是否为1来判断。这是一个概率算法,如果为1,不一定为素数,不为1,则必定...
  • 这里列举一些素数筛法,也许会有帮助埃氏筛法(Sieve of Eratosthenes)笔者在早接触数论时,就学到的算法 思路比较简单: 对于每个素数,都枚举其倍数打上标记 那么没打过标记的就都是素数了 示例程序:
  • 素数筛是一个可以快速生成素数表的算法,比起来一个数字一个数字的判断,欧拉筛和埃式筛可以大大减少时间复杂度,这两种方法也是常用的两种方法 埃式筛: 素数的倍数是合数 将所有的合数标记了,那剩下没有标记...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 162
精华内容 64
关键字:

最快素数算法