我试图在给定范围之间打印Prime数字,但我得到空白输出。我哪里出错了?是逻辑错误还是实施错误?
#include <stdio.h>
int isPrime(int i)
{
int j;
for(j=2; j<=i; j++)
{
if(i%j==0)
{
return 0;
}
}
return 1;
}
int main()
{
int cases, n1, n2, i;
scanf("%d", &cases);
while(cases>0)
{
scanf("%d%d", &n1, &n2);
for(i=n1; i<=n2; i++)
{
if(isPrime(i))
{
printf("%d\t", i);
}
}
cases--;
}
return 0;
}
答案 0 :(得分:2)
您必须在isPrime
之前停止i
中的循环,因为所有非零数字都可以自行整除:
int isPrime(int i) {
int j;
for (j = 2; j < i; j++) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
请注意,对于0
以下的数字,您还应该返回2
。此外,您可以通过停留i
的平方根并仅测试2
以上的奇数来显着提高性能。
int isPrime(int i) {
if (i <= 2) {
return i == 2;
}
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
答案 1 :(得分:1)
i%i==0
为零,否则 i
将始终为真,因此isPrime
将为0
返回i
为2或更高。
例如,您可以使用j<i
代替j<=i
。
另一点是你的isPrime
将错误地判断所有1或更少的整数作为素数,所以你应该在循环之前检查它们。
答案 2 :(得分:1)
除了次优之外,当你试图找到除数时,你的代码会一直到i
。这意味着所有检查最终都会在i == j
时成功,因此i%j
为零。
循环的更好停止条件是
for( j=2 ; j*j <= i ; j++)
换句话说,在通过i
的平方根时停止。这是有效的,因为如果你没有找到小于平方根的适当除数,那么可以保证也没有大于平方根的除数。
如果你知道n2
的上限,你可以通过预先计算所有素数到sqrt(n2)
并使用它们测试其他数字是否为素数来使你的解决方案更快。
答案 3 :(得分:0)
首先,2是素数。每个数字都可以自行整除。所以这个条件
if(i%j==0)
当true
等于j
时,将始终等于i
。
该功能可以按以下方式编写
int isPrime( unsigned int x )
{
int prime = ( x == 2 ) || ( x % 2 != 0 && x > 2 );
for ( unsigned int i = 3; prime && i * i <= x; i += 2 )
{
prime = x % i != 0;
}
return prime;
}