我对编程很新,我想尝试编写一个程序来查找一系列数字中的素数。当我通过编译器运行这个程序时,我没有得到任何错误,但当我尝试实际运行该程序时,它说只有2,这是不正确的。我认为它应该是大约168.如果你能帮我指出我的错误,我会很感激。提前致谢!
#include <stdio.h>
#include <math.h>
void primeFinder(void);
int main(void)
{
printf("Prime numbers from 1 to 1000:\n\n");
primeFinder();
return 0;
}
void primeFinder(void)
{
int i;
int j;
int k;
int n_primes = 0;
//i is the number to be tested:
for ( i = 2 ; i <= 1000 ; i++ )
{
//i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
for ( j = 2, k = 0 ; j <= sqrt(i) ; j++ )
{
//i is not prime, whatever is the value of j:
if ( i % j == 0 )
{
//If remainder is 0, there is no need to test that i anymore:
break;
}
else
{
k++;
}
} //End of inner for
//i is prime:
if ( k == i - 2 )
{
printf("%d\t", i);
n_primes++;
}
} //End of outer for
printf("\n\nIt was found %d prime(s) in the inverval considered.\n", n_primes);
}
答案 0 :(得分:1)
我给初学者程序员提供的一个建议是:“认为模块化!”换句话说,训练自己分裂和征服;我怎样才能将问题分解为基本组成部分?
您的计划的一个好框架如下:
#include <stdio.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
BOOL is_prime(int number);
int main()
{
printf("Prime numbers between 1 and 1000:\n");
int i;
for (i = 1; i <= 1000; ++i)
{
if (is_prime(i))
{
printf("%d\n", i);
}
}
return 0;
}
// ...
这是因为,稍后,如果您需要确定数字是否为素数,您只需复制并粘贴现有的实现即可。
以下是is_prime
的一个实现,我经常使用并完成相当好的工作:
BOOL is_prime(int number)
{
// If the number is less than two, then it is not prime.
if (number < 2)
{
return FALSE;
}
// If the number is two, then it is prime.
if (number == 2)
{
return TRUE;
}
// If the number is even, then it is not prime.
if (number % 2 == 0)
{
return FALSE;
}
// Try and divide the number by all odd numbers
// less than or equal to its square root. If
// we can, then it is not prime. Otherwise, it is.
int i;
for (i = 3; i * i <= number; i += 2)
{
if (number % i == 0)
{
return FALSE;
}
}
return TRUE;
}
答案 1 :(得分:0)
if ( k == i - 2 )
此检查错误,前一个块仅针对sqrt(i) - 2
个数字进行循环。您需要查看sqrt(i) -2
答案 2 :(得分:0)
在j
到达i
的平方根后退出内循环。因此k
不计算不分i
的完整数字。
答案 3 :(得分:0)
为什么要跟踪k
?只需设置一个标志,告诉您数字是否为素数:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
int num_primes(int limit) {
int i;
int j;
int n_primes = 0;
bool is_prime; /* note stdbool.h in the includes */
for (i = 2; i <= limit; i++) {
is_prime = true;
for (j = 2; j <= sqrt(i); j++) {
if (i % j == 0) {
is_prime = false;
break;
}
}
/* This could be written as `if (is_prime) n_primes++;` */
n_primes += is_prime;
}
return n_primes;
}
答案 4 :(得分:0)
这是你的支票。你这样做的方式有点奇怪。我认为更简单的方法是创建一个标志并将其设置为true。所以你假设这个数字是素数。正如您所经历的那样,如果您发现该数字不是素数,请将该标志设置为false。之后,检查标志是否仍为真,如果是,则打印结果。这就是我所说的:
int i;
int j;
int k;
int n_primes = 0;
bool flag;
//i is the number to be tested:
for ( i = 2 ; i <= 1000 ; i++ )
{
//Assume it's prime
flag=true;
//i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
for ( j = 2 ; j <= sqrt((double)i) ; j++ )
{
//i is not prime, whatever is the value of j:
if ( i % j == 0 )
{
//If remainder is 0, there is no need to test that i anymore:
flag=false;
break;
}
} //End of inner for
//i is prime:
if ( flag==true )
{
printf("%d\t", i);
n_primes++;
}
} //End of outer for
printf("\n\nIt was found %d prime(s) in the inverval considered.\n", n_primes);
答案 5 :(得分:0)
好像你在中间更改了算法,即不检查最高i-1
的divisiors(这很浪费),你测试到sqrt(i)
。
问题是您只更改了循环条件,但没有更新以下条件:
if ( k == i - 2 )
您有两个选择:
回滚到朴素算法并将循环条件更改为:
for( j = 2, k = 0 ; j <= i-1 ; j++ )
更改您的程序逻辑,这样您只需要知道1
以外的除数是否存在,无论这些除数的数量是多少。
答案 6 :(得分:0)
如果数字是素数,k
将增加到sqrt(i)
的值。正如你所见,if条件并不总是正确的。
而不是使用计数器,你只需要一个标志来知道它是否是素数。也许是这样的:
//i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
for ( j = 2, k = 1 ; j <= sqrt(i) ; j++ )
{
//i is not prime, whatever is the value of j:
if ( i % j == 0 )
{
//If remainder is 0, there is no need to test that i anymore:
k = 0;
break;
}
} //End of inner for
if (k) // i is prime
{
...
答案 7 :(得分:0)
问题在于
if ( k == i - 2 )
i的值是固定的,k是变化的。因此,以下行仅针对i = 2和3执行。因此,您将得到答案2.
if ( k == i - 2 )
{
printf("%d\t", i);
n_primes++;
}
您可能会发现以下代码非常有用:
#include<stdio.h>
#include<math.h>
#define TRUE 1
#define FALSE 0
int isPrimeNumber(int num)
{
int i=2;
int len=sqrt(num);
if(num<2) return FALSE;
while(i<=len)
{
if(num%i==0)
{
return FALSE;
}
i++;
}
return TRUE;
}
int countPrimeNumbersInRange(int start, int end)
{
int count=0;
while(start<=end)
{
if(isPrimeNumber(start))
{
printf("%d\t",start);
count++;
}
start++;
}
return count;
}
int main()
{
printf("\n\nIt was found %d prime(s) in the inverval considered.\n", countPrimeNumbersInRange(1, 1000));
return 0;
}