在数组中存储素数的最有效方法是什么

时间:2013-04-09 15:49:59

标签: java algorithm

我希望使用有效的算法将主要数字存储在数组中,最高可达n = 100000.我使用基本方法存储素数,但这需要更多时间。

       void primeArray(){
        int primes[100000],flag=0,k=2; 
        primes[0]=2;
        primes[1]=3;
        for(int i=5;i<n;i=i+2){
                for(int j=2;j<i/2;j++){
                    if(i%j==0){
                    flag=1;
                    break;
                   }
                }

            if(flag==0){
                primes[k]=i;
                k++;
            }

            flag=0;
       }   
     }

6 个答案:

答案 0 :(得分:2)

我假设您已经知道如何计算质数并且正在寻找一种紧凑的方式来存储它们。

如果“最有效”是指“压缩到可能的最小空间”,则有一种方法可以在一个比特阵列中存储素数,该比特大约是在比特阵列中存储真/假标志的一半。

诀窍是除了2,3和5之外的所有素数都是30x加1,7,11,13,17,19,23或29的形式。因此,你可以将1到30的质数存储在一个字节(忽略2,3,5),然后在单个字节中从31到60的素数,然后从61到90的素数,依此类推。你必须分别处理2,3和5。

我们以67为例。使用整数除法计算67/30 = 2,因此您将查看素数指示字节数组的索引2处的字节。然后67 - 30 * 2 = 7,这是该字节的第二位,所以你看那里,找到一个,结论67是一个素数。

使用这种方法,您可以在33,334字节中存储少于一百万的素数。有关详细信息,请查看my blog

答案 1 :(得分:0)

使用Set甚至List等集合。由于主要数字必须是唯一的,因此Set应该是明显的选择。

例如:Set<Long> set = new HashSet<Long>();

答案 2 :(得分:0)

// initialize list
ArrayList primes = new ArrayList();

// add another number
primes.add(newPrime);

// convert to primitive array  
primes.toArray();  

答案 3 :(得分:0)

2和3也是素数:你想要包含它们。

通过在O(n^2)期间迭代第二个循环,您可以将算法的复杂性从O(n^{3/2})提高到j * j <= i

或者您可以使用Sieve of Erastosthenes O(n log log n)

答案 4 :(得分:0)

数组中的每个整数都有32位。

所以你可以按照这个

if(isPrime(n))
a[n/32]=a[n/32]|(1<<(n%32));

这样您将第n位设置为1,这意味着n是素数。只是你可以存储

更多具有更少记忆的素数,你可以使用Atkin的筛子进行有效的初步检查。

http://en.wikipedia.org/wiki/Sieve_of_Atkin

答案 5 :(得分:0)

9592素数低于100000.低于100000的所有数字都可以用17 bits表示(因为2 ^ 17是131072)。此外,所有素数但素数2都是奇数,因此最后一位会有0 - 我们可以在16 bits2 bytes中表示低于100000的每个素数。因此,使用9591个素数和一个关于素数2的特殊规则来创建一个双字节数组。这会提供19182 bytes个数据。