【发布时间】:2017-09-25 18:03:39
【问题描述】:
#include <stdio.h>
#include <math.h>
void sieve(unsigned int up, unsigned int low, unsigned char primes[]);
main()
{
unsigned int low, up;
unsigned int steps;
scanf("%d",&steps);
for (unsigned int i=0;i<steps;i++){
scanf("%d %d",&low,&up);
unsigned char v[up-low];
sieve (up, low, v);
for(unsigned int j=0; j<up-low+1; j++){
if (v[j] == 1){
printf("%d\n",low+j);
}
}
}
}
//-------------------------------------------------------------------
void sieve(unsigned int up, unsigned int low, unsigned char primes[])
{
for (unsigned int i=0;i<up-low+1;i++){
primes[i]=1;
}
for (unsigned int i=2;i<sqrt(up+1);i++) {
for (int j=((low/i)*i)+i;j<up+1;j+=i){
primes[j-low] = 0;
}
}
}
我正在尝试从特定范围内查找素数。我正在使用 Erastothenes 的分段筛,但不幸的是它丢失了一些素数,这是因为:
for (int j=((low/i)*i)+i;j<up+1;j+=i){
primes[j-low] = 0;
当i 大于我的下限时,筛子函数开始用0 值标记素数,毕竟它们不在我的标准输出中。
例如标准输入:
1
2 1000
例如标准输出:
2
37 它会丢失 2 到 37 之间的所有素数
41
43
...
还有一件事,下限值总是被算法识别为质数。
例如标准输入:
4 10例如标准输出:
4
5
7
我需要一些帮助来调整我的算法以正确标记这些数字,因为几个小时后我真的不知道我需要什么条件才能让它工作。
【问题讨论】:
-
for (unsigned int i=0;i<up-low+1;i++){primes[i]=1;}不匹配unsigned char v[up-low]; -
它是0或1个值的char数组,由上到下决定这个数组的大小,这里什么不匹配?
-
unsigned char v[up-low];的最后一个有效索引是up-low-1,但您正在循环中访问primes[up-low]。 -
发布的代码没有(干净地)编译。除此之外,
main()函数始终使用int作为返回类型(无论 Visual Studio 接受什么 -
函数:
sieve()包含signed int和unsigned int之间的几个“隐式”转换,您应该更正这些问题。编译时,始终启用所有警告,然后修复这些警告。