汗顏,數學符號表達今天才學會呀-_-#
下面是百度百科對質數的定義
質數(prime number)又稱素數,有無限個。質數定義為在大于1的自然數中,除了1和它本身以外不再有其他因數。
1、傻子求質數法
這種方法十分無腦,任何一個人都能想出來,但這種方法竟然還有幾個優化ORZ
時間復雜度是O($N^{2}$);
1.1、無優化版本
1 void prime() 2 { 3 int N = 10000; 4 int primes[N],pos=0; 5 register int i,j; 6 for(i=2;i<N;i++){ 7 bool Flag=0; 8 for(j=2;j<i;j++) 9 if(i%j==0)Flag=1; 10 if(Flag==0)primes[++pos]=i; 11 } 12 }
這也是所有求質數中最樸素的求法,自然在平常當中不會使用。
然而有些奇葩題目,求質數的次數很少,就可以用這個啦。↖(^ω^)↗
證明:質數定義為在大于1的自然數中,除了1和它本身以外不再有其他因數?——百度百科。
1.2、n/2 優化版本
1 void prime() 2 { 3 int N = 10000; 4 int primes[N],pos=0; 5 register int i,j; 6 for(i=2;i<N;i++){ 7 bool Flag=0; 8 for(j=2;j<=i/2;j++) 9 if(i%j==0)Flag=1; 10 if(Flag==0)primes[++pos]=i; 11 } 12 }
?
這種優化就比上一種快一倍(時間復雜度),但仍然有缺陷,能不能再快一點??_?
證明:x/2以上的數增加就會重復。
1.3、n開平方優化版本
1 void prime() 2 { 3 int N = 10000; 4 int primes[N],pos=0; 5 register int i,j; 6 for(i=2;i<N;i++){ 7 bool Flag=0; 8 for(j=2;j<=sqrt(n);j++) 9 if(i%j==0)Flag=1; 10 if(Flag==0)primes[++pos]=i; 11 } 12 }
?這個就是傻子求法的最終版本了,時間復雜度已經優化到了極限(個人認為)。囧rz
證明:因為x=$\sqrt{N}^{2}$的平方,所以sqrt(x)以上的數增加就會重復。
?
?2、埃氏(Eratosthenes)篩法
埃拉托斯特尼篩法,簡稱埃氏篩或愛氏篩,是一種由希臘數學家埃拉托斯特尼所提出的一種簡單檢定素數的算法。要得到自然數n以內的全部素數,必須把不大于根號n的所有素數的倍數剔除,剩下的就是素數。——百度百科
這種篩法大概是我初一學了快一個學期,開始學質因數時,自己過不了找質數一個題,然后接觸的一個算法。
埃氏的篩法思想精華,主要是把質數的倍數剔除,剩下的那些就是質數。+_+
這種算法的時間復雜度是O(nloglogn)。
1 void prime() 2 { 3 int N=10000; 4 register int i,j; 5 bool prim[N]; 6 memset(prim,0,sizeof(prim)); 7 prim[1]=1; 8 for(i=2;i<=sqrt(N);i++) 9 if(prim[i]==0) 10 for(j=i+i;j<=N;j+=i) 11 prim[j]=1; 12 }
3、歐拉(Euler)篩選法
歐拉篩法就是所謂中的高級篩法,時間復雜度削減到了O(N)。
它的思想是在埃氏篩法的基礎上,讓每個合數只被它的最小質因子篩選一次,以達到不重復的目的。
1 void prime() 2 { 3 int N=10000; 4 int prim[N],bz[N],top=0; 5 memset(bz,0,sizeof(bz)); 6 register int i,j; 7 for(i=2;i<=N;i++){ 8 if(!bz[i])prim[++top]=i; 9 for(j=0;j<=top&&i*prim[j]<=N;j++){ 10 bz[i*prim[j]]=1; 11 if(i%prim[j]==0)break; 12 } 13 } 14 }
自己還有很多東西都沒有學到,不知道什么時候才能脫掉蒟蒻的外套呢。
博主是初中蒟蒻,能力弱,還請大家多多提出改進建議:-D ? ? ——2018.11.27
?