[英]Prime Number Generator in C
這是問題的鏈接: http : //www.spoj.com/problems/PRIME1/
基本上我們得到兩個限制,我們必須打印出它們之間的所有素數......
這是我的代碼(語言 == C):
#include <stdio.h>
void IsPrime(int test){
for(int i= 2; i<test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
int main(){
int T,lower,upper;
scanf("%d",&T);
while(T--){
scanf("%d",&lower);
scanf("%d",&upper);
for(int i = lower;i<=upper;i++){
if(i>1){
IsPrime(i);
}
}
}
return 0;
}
在我的本地機器上,我運行了它,它適用於簡單的測試用例......我來自網站的消息是超時錯誤,所以我想知道是否有更有效的方法來解決這個問題,因為顯然我解決的速度不夠快?
首先,你不必檢查n中的每個數字來確定n是否為素數,只有它的平方根(有一個數學證明,現在不給它)。 所以:
void IsPrime(int test){
// i <= sqrt(test)
// but to avoid sqrt you can do i * i <= test
for(int i= 2; i * i <= test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
接下來,我們知道在2之后,所有其他素數都是奇數,所以如果我們將2視為特例,我們可以循環2:
// Do greater than one check only once
if (lower > 1) {
// Special case - lower is 2
if (lower == 2) {
printf("%d\n", 2);
++lower;
}
for(int i = lower; i <= upper; i += 2){
IsPrime(i);
}
}
但是,由於你必須做T次,所以你最終會做的不僅僅是需要的檢查。 此外,這個問題限制了n和m,所以它基本上是完美的篩子,正如@HennoBrandsma所說。
使用這些優化,您應該找到所有素數到限制,並將它們存儲在容器中。 然后,當提示范圍時,只需移動篩子並打印出數字。
(這將要求您更多地更改IsPrime功能 - 而不是立即打印數字,讓它返回true或false,然后根據它,將數字添加到容器中)
您可以嘗試以下方法,對測試次數進行略微優化,並跳過任何大於2
偶數值:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i * i <= v; i+=2)
if (v % i == 0)
return 0;
return 1;
}
如果您可以使用數學庫和math.h
,以下可能會更快:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i <= sqrt (v); i+=2)
if (v % i == 0)
return 0;
return 1;
}
我將這兩個版本的時間定義在int
范圍內的值為1-2百萬之間並且它們很接近。
注意:在使用重復調用的實際測試中, i * i <= v
(下面的isprime2
)的版本始終比使用i <= sqrt (v)
(下面的isprime3
)的調用快。 例如:
$ ./bin/isprimetst2
isprime (1.650138 sec) - 78497 primes
isprime2 (0.805816 sec) - 78497 primes
isprime3 (0.983928 sec) - 78497 primes
短驅動程序遍歷0-2000000
所有素數,例如:
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime2 (v);
t2 = clock ();
printf (" isprime2 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime3 (v);
t2 = clock ();
printf (" isprime3 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
您可以在C中使用庫maths.h並使用sqrt函數計算給定數字的平方根。 所以程序可能是這樣的:
#include <stdio.h>
#include <maths.h>
int isPrime(int number){
int i;
if(number % 2 == 0){
return;
}
for(i=3; i<=sqrt(number); i++){
if(number % i == 0){
return;
}
printf("%d\n",number);
}
int main(){
int lower,upper,i;
if(lower >1){
if(lower == 2){
printf("2\n");
}
for(i=lower; i<=upper; i++){
isPrime(i);
}
return 0;
}
簡而言之,您可以使用if-else條件來使用一些額外的檢查(如if(number%2 == 0))來降低程序的時間復雜度。例如,一個新的if條件可能是if(number%5 == 0) )等等,所以在這些條件的幫助下,檢查不會在許多情況下進行循環,這會減少程序的時間。
#include<stdio.h>
int main()
{
int low,high,j;
int prime(int);
int t;
scanf("%d",&t);
while (t>0)
{
scanf("%d %d",&low,&high);
while (low<=1)
{
low++;
continue;
}
for (j=low;j<=high;j++)
{
if (prime(j)){
printf("%d\n",j);
}
}
printf("\n");
t--;
}
return 0;
}
int prime(int n)
{
int i;
for (i=2;i*i<=n;i++)
{
if (n%i==0){
return 0;
}
}
return 1;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.