Java 埃拉托斯烯优化筛两个数之间的素数之和
下面是我编写的代码,它为我提供了Java 埃拉托斯烯优化筛两个数之间的素数之和,java,optimization,primes,sieve-of-eratosthenes,Java,Optimization,Primes,Sieve Of Eratosthenes,下面是我编写的代码,它为我提供了n和m之间的素数之和 class TestClass { final static int MAX=1000000; final static boolean[] isPrime=isPrime(); public static void main(String args[] ) throws Exception { BufferedReader keyboard= new BufferedReader(new InputS
n
和m
之间的素数之和
class TestClass {
final static int MAX=1000000;
final static boolean[] isPrime=isPrime();
public static void main(String args[] ) throws Exception {
BufferedReader keyboard= new BufferedReader(new InputStreamReader(System.in));
int t=Integer.parseInt(keyboard.readLine());
while(t>0 && t<=100){
String[] tempInt=keyboard.readLine().split(" ");
int n=Integer.parseInt(tempInt[0]);
int m=Integer.parseInt(tempInt[1]);
int sum=primeSum(n,m);
System.out.println(sum);
t--;
}
}
private static int primeSum(int n, int m) {
int sum=0;
for(int i=n;i<=m;i++){
if(isPrime[i]){
sum=sum+i;
}
}
return sum;
}
private static boolean[] isPrime(){
int maxFactor= (int)Math.sqrt(MAX);
boolean[] isPrime=new boolean[MAX + 1];
int len=isPrime.length;
Arrays.fill(isPrime,true);
isPrime[0]=false;
isPrime[1]=false;
for(int i=0;i<=maxFactor;i++){
if(isPrime[i]){
for(int j=i+i;j<len;j+=i){
isPrime[j]=false;
}
}
}
return isPrime;
}
}
输出:
454396537
448660141
现在,我正试图进一步优化筛子,只取奇数,这在实践中是常见的。
下面是我编写的优化筛函数
private static boolean[] isPrime(){
int root=(int) Math.sqrt(MAX)+1;
int limit=(MAX-1)/2;
boolean[] isPrime=new boolean[limit];
Arrays.fill(isPrime, true);
root = root/2 -1;
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;
}
i、 e 3 5 7 9,11 13 1,17 19,2,1,23 2,5,2,7,29 31,3,3,3,5,37 3,9等等
现在真正困扰我的是我在primeSum()方法中为这个优化筛做的索引
private static int primeSum(int n, int m) {
int sum;
if(n>0 && n<=2){
sum=2;
}else
sum=0;
//System.out.println(sum);
for( int i = (n-3)/2; i <= (m-3)/2 ; i++){
if(isPrime[i]){
//System.out.println(i);
sum=sum+2*i+3;
}
}
return sum;
}
但当我必须在范围内找到它时,它仍然失败
1 2
1 1
2 2
那么,我是否应该再次包含这些情况并单独处理?我在primeSum()中编制i
索引的方法是否正确?或者我可以用更好的方式完成它吗?还有什么其他可能的索引方法呢?为什么不循环查找n
和m
之间的每一个奇数:
private static int primeSum(int n, int m) {
int sum = 0;
if (n <= 2 && m >= 2) // need this because 2 not in isPrime
sum += 2;
if (n%2 == 0) // always start from an odd number
n++;
for (int i = n; i <= m; i += 2) {
int index = (i - 3)/2;
if (index >= 0 && isPrime[index]) {
sum += i;
}
}
return sum;
}
私有静态int素数和(int n,int m){
整数和=0;
if(n=2)//需要这个,因为2不在iPrime中
总和+=2;
if(n%2==0)//始终从奇数开始
n++;
对于(int i=n;i=0&&isPrime[index]){
总和+=i;
}
}
回报金额;
}
可能更适合@reto oK移动它:)您可能想在此处删除它。
if(n>0 && n<=2){
sum=2;
n=n+2;
}
1 2
1 1
2 2
private static int primeSum(int n, int m) {
int sum = 0;
if (n <= 2 && m >= 2) // need this because 2 not in isPrime
sum += 2;
if (n%2 == 0) // always start from an odd number
n++;
for (int i = n; i <= m; i += 2) {
int index = (i - 3)/2;
if (index >= 0 && isPrime[index]) {
sum += i;
}
}
return sum;
}