我正在做项目欧拉,我遇到了这个问题。我在VS 2013中运行代码,程序因溢出而崩溃。
这是我的方法:
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\n", 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\n", prime);
sum += prime;
}
iter++;
}
printf("Sum of prime is: %d\n", sum);
*/
}
此方法包括两种计算范围PRIME_LIMIT
中所有素数之和的方法。第二种方法需要很长时间才能得到结果,并且可能需要一整天。第一种方法是使用Atkin筛,程序崩溃!
我的代码中有错误吗?请帮忙!
答案 0 :(得分:2)
所以,让我们谈谈这个问题:
与Java非常相似,C中的整数对它们可以容纳的大小有限制。在这里,您选择使用long long int
。幸运的是,对于这个问题,总和将适合该数据类型。对于其他Project Euler问题,您需要使用BigInt类。
如果添加一个添加,那么缓慢的方法实际上很好。我们知道,我们需要搜索的除数列表实际上小于2 ... n
中的所有数字。所以我们可以将你的一个循环更改为:
int max = ciel(sqrt(iter));
for (int a = 2; a < max; a++)
if (prime % a == 0)
isDivisible = true;
break;
如果我们这样做,您的代码将相对较快地完成。
我还没有完全通过这段代码,因为它看起来不像我记得的eratosthenes的筛子,但至少,你将用你的分配溢出堆栈。
#define PRIME_LIMIT 2000000
bool isPrime[PRIME_LIMIT+1];
让我们解决一下:
#define PRIME_LIMIT 2000000
static bool isPrime[PRIME_LIMIT+1]
或者:
#define PRIME_LIMIT 2000000
bool *isPrime = calloc(PRIME_LIMIT + 1, sizeof(bool));
我真的建议不要试图实现Atkin的Sieve。如果我要将其作为一个学习练习来实现,我会按此顺序执行:
你上面做的很慢的方法。在python中,类似的代码大约需要1分钟来解决问题。我怀疑C可以在大约10秒(或更快)的时间内完成。
sieve of eratosthenes是一个更简单的实施筛子。我建议下次使用它。
然后尝试实施sieve of atkin。对于这种尺寸的问题,这种速度的算法完全没有必要。