欧拉 10,质数之和到 2000000
Euler 10, Sum of primes to 2000000
我的算法有问题。我在下面的任务中找不到哪里出错了。
描述:
The sum of the primes below 10
is 2 + 3 + 5 + 7 = 17
.
Find the sum of all the primes below two million.
这是我在 C 中的解决方案:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
bool *numbers = (bool *)malloc(sizeof(bool) * 2000000);
unsigned long run = 1;
while (run < 2000000) {
numbers[run] = true;
run++;
}
unsigned long sum = 0;
for (long i = 2; i < 2000000; i++) {
if (numbers[i] == true) {
for (long x = 2 * i; x < 2000000; x += i) {
numbers[x] = false;
}
}
}
run = 0;
while (run < 2000000) {
if (numbers[run] == true) {
sum = sum + run;
}
run++;
}
printf("%d\n", sum-1); // cause 1
free(numbers);
return 0;
}
感谢帮助!!!
您可以尝试以下方法:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long int i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
char *primes; // only needs to be used as a flag holder
primes = malloc(sizeof(char)*limit); // flag of is prime or not
if(primes==NULL) {
perror("main, malloc");
return(-1);
} // else
for (i=2;i<limit;i++) // set the flags to True to start
primes[i]=1;
for (i=2;i<limit;i++) // now go through all combos
if (primes[i]) // already know; no need
for (j=i;i*j<limit;j++) // has i and j as factors
primes[i*j]=0; // not prime
for (i=2;i<limit;i++) // now add them up
if (primes[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long or %llu for long long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
您还可以使用 calloc
与 malloc
反转搜索以标记合数而不是素数并保存循环(感谢 ):
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(){
unsigned long i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
bool * composite = (bool *)calloc(limit, sizeof(bool));
if(composite==NULL) {
perror("main, calloc");
return(-1);
}
for (i=2;i<limit;i++) // now go through all combos
if (!composite[i])
for (j=i;i*j<limit;j++) // has i and j as factors
composite[i*j]=true; // composite; not prime
for (i=2;i<limit;i++) // now add them up
if (!composite[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
同时打印:
There are 148933 primes less than 2000000 with a sum of 142913828922
注:
- 对保证为 64 位的总和使用
long long
。虽然长可能是 32 位或 64 位,而 int
可能 短至 16 位。 See C data types
- 确保
printf
type and length 说明符在给定打印数据类型的情况下是正确的。
您的代码中的问题是您没有为类型为 unsigned long
的 sum
使用正确的 printf
转换说明符:您应该写成:
printf("%lu\n", sum);
结果 142913828923
超出了 32 位整数的范围,因此您实际上应该使用更大的类型,例如 long long
保证至少有 63 个值位。最后一个循环应该从 2
开始,以避免将 1
计为质数。
这是经过一些改进的修改版本:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
int limit = 2000000;
bool *numbers = (bool *)malloc(sizeof(bool) * limit);
if (numbers == NULL) {
printf("not enough memory\n");
return 1;
}
for (int run = 0; run < limit; run++) {
numbers[run] = true;
}
for (long long i = 2; i * i < limit; i++) {
if (numbers[i] == true) {
for (long long x = i * i; x < limit; x += i) {
numbers[x] = false;
}
}
}
long long sum = 0;
for (int run = 2; run < limit; run++) {
if (numbers[run] == true) {
sum = sum + run;
}
}
printf("%lld\n", sum);
free(numbers);
return 0;
}
我的算法有问题。我在下面的任务中找不到哪里出错了。
描述:
The sum of the primes below
10
is2 + 3 + 5 + 7 = 17
. Find the sum of all the primes below two million.
这是我在 C 中的解决方案:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
bool *numbers = (bool *)malloc(sizeof(bool) * 2000000);
unsigned long run = 1;
while (run < 2000000) {
numbers[run] = true;
run++;
}
unsigned long sum = 0;
for (long i = 2; i < 2000000; i++) {
if (numbers[i] == true) {
for (long x = 2 * i; x < 2000000; x += i) {
numbers[x] = false;
}
}
}
run = 0;
while (run < 2000000) {
if (numbers[run] == true) {
sum = sum + run;
}
run++;
}
printf("%d\n", sum-1); // cause 1
free(numbers);
return 0;
}
感谢帮助!!!
您可以尝试以下方法:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long int i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
char *primes; // only needs to be used as a flag holder
primes = malloc(sizeof(char)*limit); // flag of is prime or not
if(primes==NULL) {
perror("main, malloc");
return(-1);
} // else
for (i=2;i<limit;i++) // set the flags to True to start
primes[i]=1;
for (i=2;i<limit;i++) // now go through all combos
if (primes[i]) // already know; no need
for (j=i;i*j<limit;j++) // has i and j as factors
primes[i*j]=0; // not prime
for (i=2;i<limit;i++) // now add them up
if (primes[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long or %llu for long long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
您还可以使用 calloc
与 malloc
反转搜索以标记合数而不是素数并保存循环(感谢
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(){
unsigned long i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
bool * composite = (bool *)calloc(limit, sizeof(bool));
if(composite==NULL) {
perror("main, calloc");
return(-1);
}
for (i=2;i<limit;i++) // now go through all combos
if (!composite[i])
for (j=i;i*j<limit;j++) // has i and j as factors
composite[i*j]=true; // composite; not prime
for (i=2;i<limit;i++) // now add them up
if (!composite[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
同时打印:
There are 148933 primes less than 2000000 with a sum of 142913828922
注:
- 对保证为 64 位的总和使用
long long
。虽然长可能是 32 位或 64 位,而int
可能 短至 16 位。 See C data types - 确保
printf
type and length 说明符在给定打印数据类型的情况下是正确的。
您的代码中的问题是您没有为类型为 unsigned long
的 sum
使用正确的 printf
转换说明符:您应该写成:
printf("%lu\n", sum);
结果 142913828923
超出了 32 位整数的范围,因此您实际上应该使用更大的类型,例如 long long
保证至少有 63 个值位。最后一个循环应该从 2
开始,以避免将 1
计为质数。
这是经过一些改进的修改版本:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
int limit = 2000000;
bool *numbers = (bool *)malloc(sizeof(bool) * limit);
if (numbers == NULL) {
printf("not enough memory\n");
return 1;
}
for (int run = 0; run < limit; run++) {
numbers[run] = true;
}
for (long long i = 2; i * i < limit; i++) {
if (numbers[i] == true) {
for (long long x = i * i; x < limit; x += i) {
numbers[x] = false;
}
}
}
long long sum = 0;
for (int run = 2; run < limit; run++) {
if (numbers[run] == true) {
sum = sum + run;
}
}
printf("%lld\n", sum);
free(numbers);
return 0;
}