[英]Sum of Primes between two number from Optimized 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 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;
}
}
輸入:
2
1 99999
10000 99999
輸出:
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;
}
我能夠做到的。 我測試了上述功能,直到MAX=100
為止。 這是Ideone Link IDEONE LINK測試結果
truetruetruefalsetruetruefalsetruetruefalsetruefalsefalsetruetruefalsefalsetrue
falsetruetruefalsetruefalsefalsetruefalsefalsetruetruefalsefalsetruefalse
truetruefalsefalsetruefalsetruefalsefalsetruefalsefalsefalsetruefalse
即3 5 7 9̶11 13 1̶5̶17 19̶2̶1̶23 2̶5̶2̶7̶29 31̶3̶3̶̶3̶5̶37 3̶9̶等。
現在真正困擾我的是我在primeSum() method
為優化過的篩子所做的索引primeSum() method
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;
}
但顯而易見, n
索引在n<3
失敗。 所以我必須這樣做才能使此代碼正常工作
if(n>0 && n<=2){
sum=2;
n=n+2;
}
但是,當我必須在范圍之間找到它時,它仍然失敗
1 2
1 1
2 2
所以我應該再次包括這些情況並分別處理嗎?, i
在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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.