Calculating sum of prime number below 2 million by using Sieve of Atkin
我在做项目欧拉,我遇到了这个问题。我在vs 2013中运行代码,程序因为溢出而崩溃。
这是我的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | void problem10() { long long int iter = 2, sum = 0; //Sieve of Atkin bool isPrime[PRIME_LIMIT+1]; for (long long int i = 5; i <= PRIME_LIMIT; i++) { isPrime[i] = false; } long long int lim = ceil(sqrt(PRIME_LIMIT)); for (long long int x = 1; x <= lim; x++) { for (long long int y = 1; y <= lim; y++) { long long int n = 4 * x*x + y*y; if (n <= PRIME_LIMIT && (n % 12 == 1 || n % 12 == 5)) { isPrime[n] = true; } n = 3 * x*x + y*y; if (n <= PRIME_LIMIT && (n % 12 == 7)) { isPrime[n] = true; } n = 3 * x*x - y*y; if (x > y && n < PRIME_LIMIT && n % 12 == 11) { isPrime[n] = true; } } } // eliminate composites by seiving for (long long int n = 5; n <= lim; n++) { if (isPrime[n]) { for (long long int k = n*n; k <= PRIME_LIMIT; k+= k*k) { isPrime[k] = false; } } } for (long long int n = 5; n <= PRIME_LIMIT; n++) { if (isPrime[n]) { sum += n; } } sum = sum + 2 + 3; printf("%lld ", sum); /* //A basic approach -- too slow while (iter < PRIME_LIMIT) { bool isDivisible = false; int prime = iter; for (int a = 2; a < iter; a++) { if (prime%a == 0) { isDivisible = true; break; } } if (isDivisible){} else { //printf("prime is: %d ", prime); sum += prime; } iter++; } printf("Sum of prime is: %d ", sum); */ } |
该方法包括两种方法来计算
我的密码有错误吗?请帮忙!
那么,我们来谈谈这个问题:
整数大小与Java非常类似,C中的整数限制了它们适合的大小。在这里,您选择使用
如果你再加一个,这个缓慢的方法实际上是可以的。我们知道,我们需要搜索的除数列表实际上比
1 2 3 4 5 | int max = ciel(sqrt(iter)); for (int a = 2; a < max; a++) if (prime % a == 0) isDivisible = true; break; |
如果我们这样做,您的代码将相对较快地完成。
你的快速方法我还没有完全读完这段代码,因为我记得它不像是埃拉托斯滕的筛子,但至少,你的分配会溢出堆栈。
1 2 | #define PRIME_LIMIT 2000000 bool isPrime[PRIME_LIMIT+1]; |
让我们来解决这个问题:
1 2 | #define PRIME_LIMIT 2000000 static bool isPrime[PRIME_LIMIT+1] |
或:
1 2 |
建议
我真的建议你不要从实施阿特金的筛选开始。如果我将此作为学习练习来实施,我将按以下顺序执行:
你上面所做的缓慢的方法。在Python中,类似的代码需要大约1分钟来解决问题。我怀疑C能在10秒钟内完成(或更快)。
埃拉托斯滕斯筛网是一种简单得多的筛网。我建议下一步使用它。
然后尝试实施阿特金的筛选。不过,对于这种规模的问题,这种速度的算法是完全不必要的。