[英]Program to find prime numbers prints out two
我是編程的新手,我想嘗試編寫一個程序來查找一定范圍內的質數。 當我通過編譯器運行該程序時,沒有出現任何錯誤,但是當我嘗試實際運行該程序時,它說只有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);
}
我給初學者程序員一個我發現實際上有幫助的建議是:“考慮模塊化 !” 換句話說,訓練自己去分裂和征服。 如何將問題分解為基本要素?
一個適合您程序的框架如下:
#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;
}
if ( k == i - 2 )
此檢查是錯誤的,則前一個塊僅針對sqrt(i) - 2
數字循環。 您需要檢查sqrt(i) -2
當j
到達i
平方根后,退出內部循環。 因此, k
不會計算不除i
的整數的總數。
為什么還要跟蹤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;
}
這是您的支票。 您執行此操作的方式有些奇怪。 我認為更簡單的方法是創建一個標志並將其設置為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);
似乎您在中間更改了算法,即,您直到sqrt(i)
都進行了測試,而不是檢查直到i-1
除數(這很浪費sqrt(i)
。
問題是您僅更改了循環條件,但沒有更新以下條件:
if ( k == i - 2 )
您有2個選擇:
回滾到朴素算法,並將循環條件更改為:
for( j = 2, k = 0 ; j <= i-1 ; j++ )
更改程序邏輯,以便您僅需要知道除數是否存在 1
以外的除數,而與此類除數的數量無關。
如果數字是素數,則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
{
...
問題出在
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.