大素數高效演算法判斷
阿新 • • 發佈:2019-02-16
前段日子我也在做素數,下面是我的一個總結,看到那個2秒搞定的,我還真想去看看
當數字小於1000000時,可以用簡單的判斷
int isprime(int n)
{
int i;
for(i=2;i<=sqrt(n);i++)
if (n%i==0)
return 0;
return 1;
}
但當數值在1000000到100000000時
介紹一種方法
prime={2,3,5,7,11,13,17,……}為事先做好的素數表 如果需要判斷的數最大為100000000,則prime的最大元素為大於10000的最小素數即可
//素數表生成法: int t[10010]={0},prime[3000];//3000可能有點大,具體多少運行了,就知道了 int len; void getprime(void) { int i,j; t[0]=t[1]=1; //t[i]=1,表示該數不是素數,被篩除 for(i=2;i <=sqrt(10010);i++) { if(!t[i]) { for(j=i+i;j<10010;j+=i) t[j]=1; } } len=0; for(i=2;i <10010;i++) { if(!t[i]) prime[len++]=i; } } int isprime(long n) { int i; while(prime[i]*prime[i] <=n) { if(n%prime[i]==0) return 0; i++; } return 1; }
如果數值大於100000000時
可以用Miller-Rabbin素數測試法,判斷是否為素數
int Miller_Rabbin(long long n) { long long i,s,a; s=10; //s的值可以根據需要變大 // randomize(); for(i=0;i <s;i++) { a=long long(rand()%(n-1)+2); //自動生成受限 if(modular_exp(a,n-1,n)>1) return 0; } return 1; } long long modular_exp(long long a,long long b,long long c)//求a^b%c該函式受限 { if(a==0) return 0; if(b==0) return 1; if(b==1) return a%c; return (a*modular_exp(a,b-1,c))%c; }
最普通的篩法:(演算法競賽必會)
#include<stdio.h> #include<stdbool.h> int main (void) { int n=100,i,j; bool prime[101]; //C99 bool在#include<stdbool.h>中 memset(prime,1,sizeof(prime));//全定義為素數 prime[0]=prime[1]=0; //0和1不是素數 for (i=2; i<=sqrt(n); i++) { if(prime[i]) { for(j=i*i; j<=n; j+=i)//j=i*i是j=i+i的優化 { prime[j]=0; } } } int k=0; for(i=0; i<=n; i++) { if(prime[i]) { k++; printf("%d ",i); } } printf("\n~~~%d ",k); return 0; }