生成尽可能多的不同质数 P ,使反向(P)为 也是素数,不等于 P 。
输出:每行打印一个整数(≤10^ 15)。不要打印超过 总共10 ^ 6个整数。
评分:让 N =正确输出。 M =输出不正确。您的分数将最大(0,N-M)。
注意:P和反向(P)中只有一个将被计为正确。如果两者都在文件中,则会将其视为不正确。
样本输出 107 13 31 17 2
解释
得分为1.由于13,107,17是正确的。 31是不正确的,因为 13已经存在了。 2是不正确的。
这是我编写的代码,它在Eclipse中给出了输出Out Of Memory
错误。
由于内存要求是256 MB,我设置-Xmx256M
,但由于它给我一个Out Of Memory
错误,我一定误解了这个问题,或者我的代码在内存利用率方面有问题。我在这做错了什么?我为lONGMAX
或10000
等较小的1000000
获得了所需的输出。
public class ReversePrime {
final static long lONGMAX=1000000000000000L;
final static int MAXLISTSIZE=1000000;
final static boolean[] isPrime=isPrime();
public static void main(String...strings ){
Set<Long> reversedCheckedPrime = new LinkedHashSet<Long>();
int isPrimeLength=isPrime.length;
for(int i = 0; i < isPrimeLength ; i++){
if( isPrime[i]){
long prime = 2 * i + 3;
long revrse= reversePrime(prime);
if ( (!(prime==revrse)) && (!reversedCheckedPrime.contains(revrse)) &&
(reversedCheckedPrime.size()<=MAXLISTSIZE)){
reversedCheckedPrime.add(prime);
}
if (reversedCheckedPrime.size()==MAXLISTSIZE){
break;
}
}
}
for (Long prime : reversedCheckedPrime){
System.out.println(prime);
}
}
private static long reversePrime(long prime) {
long result=0;
long rem;
while(prime!=0){
rem = prime % 10;
prime = prime / 10;
result = result * 10 + rem ;
}
return result;
}
private static boolean[] isPrime() {
int root=(int) Math.sqrt(lONGMAX)+1;
root = root/2-1;
int limit= (int) ((lONGMAX-1)/2);
boolean[] isPrime=new boolean[limit];
Arrays.fill(isPrime, true);
for(int i = 0 ; i < root ; i++){
if(isPrime[i]){
for( int j = 2 * i * (i + 3 ) + 3, p = 2 * i + 3; j < limit ; j = j + p){
isPrime[j] = false;
}
}
}
return isPrime;
}
}
答案 0 :(得分:2)
有两种可能性:
您使用-Xmx256M
表示256 MB堆。但是,除了堆之外,你的VM可能会在尝试获取更多内容时被杀死。
您为VM提供256 MB但您的程序需要更多并被杀死。 <----
正如RealSkeptic所说,情况确实如此。
要获得1M素数,您需要调查一些&lt; 100M数字(*)。因此,如果主筛工作在100_000_000以下,它应该可以工作。这样筛子也可以反转。通过跳过平均值,您只需要50 MB,因此您可以将限制设置为100M。
您可以使用位而不是字节来减少因子8使用的内存。通过忽略以偶数开头的数字,你可以将它减少2倍,但这很复杂。
(*)这是您在提交之前可以轻松尝试的内容。
答案 1 :(得分:2)
你宣布:
final static long lONGMAX=1000000000000000L;
然后在分配布尔数组时,计算:
int limit= (int) ((lONGMAX-1)/2);
根据该定义,limit
将为1,382,236,159
。这是1.3Gb,假设布尔值占用一个字节。您可能认为VM每个布尔值只分配一个位,但这不是它的工作原理。
请考虑使用java.util.BitSet
。
答案 2 :(得分:0)
你实际上应该用List替换你的boolean [],因为内存可能来自这个表。您没有使用最佳策略,因为您将每个长期存在的所有价值都堆叠起来。 你最好只在内存中保留素数,尝试重新考虑素数的定义,并继续进行迭代演绎。