PHP輸出1到n所有素數及素數和的三種演算法

2021-10-03 06:14:54 字數 3185 閱讀 8719

素數是只能被1和本身整除的數

下面用php輸出1到n所有素數及素數和

思路:給定數n,得到2到n之間所有的數,然後依次判斷其中的每乙個數——能否被2到該數-1整除,如果被整除,則該數不為素數

演算法如下:

<?php

function

primes($n

,$s=false)}

if($sign

)$primes

=$i;//將判斷為素數的$i存入陣列

}//條件判斷,是否需要求和if(

$s)//將和以sum為鍵名存入陣列

$primes

['sum']=

$sum;}

//返回陣列

return

$primes;}

echo'';

print_r

(primes

(100000

,true))

;

以php預設執行時間30s和執行消耗記憶體128m為標準,這個演算法跑到輸出1到110000之間的素數就超過了最大執行時間30s。

接下來考慮演算法優化問題:

考慮到素數都是奇數,因此外層迴圈也沒必要執行n-1次,因為2到n裡面含有偶數,所以不用使$i每次自增1,改為自增2,這樣做的話就要在初始陣列中放入值為2的單元。考慮了外層迴圈,那內層迴圈呢?同理!

於是演算法1可以優化為下列演算法:

<?php

function

primes($n

,$s=false)}

//將判斷為素數的$i存入陣列if(

$sign

)$primes

=$i;}

//條件判斷,是否需要求和if(

$s)//將和以sum為鍵名存入陣列

$primes

['sum']=

$sum;}

//返回陣列

return

$primes;}

echo'';

print_r

(primes

(150000

,true))

;

這個演算法跑到輸出1到170000之間的素數就超過了最大執行時間30s

那繼續考慮演算法優化問題:

既然要求素數,也就是在1到n的自然數中排除合數,合數有這個性質:將合數質因數分解,必然有乙個質因數大於1小於該合數的平方根。證明如下:

假設某合數b=a1*a2*a3*...*ak(均為質數)

設a1為最小質因數,則an=b/a1為另一質數

因為a1為最小質因數

所以b/a1>a1,即b>a1^2

即sqrt(b)

>a1

所以演算法第6行可以這樣寫:

for($j

=3;$j

<=

sqrt($i

);$j+

=2);

這個演算法可以輸出1到3500000之間的素數,之後就會超過最大執行時間30s

判斷乙個數是否為素數有乙個方法:使用小於這個數的所有素數依次試除,若所有試除都有餘數,則該數也為素數

按照演算法1第一步優化,排除掉偶數,演算法如下:

function

primes($n

,$s=false)}

//將$i的值存入陣列if(

$sign

)$primes[$j

]=$i;

}//條件判斷if(

$s)//將和以sum為鍵名存入陣列

$primes

['sum']=

$sum;}

//返回陣列

return

$primes;}

echo'';

print_r

(primes

(325000

,true))

;

這個演算法可以輸出1到325000之間的所有素數,之後就會超過最大執行時間30s

考慮演算法1的全部優化過程,排除了偶數,也就是2的倍數,是不是也能排除3的倍數,5的倍數,即質數的倍數,再考慮質因數,是不是也能用最小質因數小於sqrt($n)呢。

這裡使用的方法就是篩選法:

於是就有了以下演算法:

<?php

function

primes($n

,$s=false)}

}//將primes陣列所有鍵名作為值替換primes陣列所有的值,方便下一步求和

$primes

=array_keys

($primes);

//條件判斷if(

$s)//將和以sum為鍵名存入陣列

$primes

['sum']=

$sum;}

//返回陣列

return

$primes;}

echo'';

//memory max2350000

print_r

(primes

(150000

,true))

;

這個是想到的更完美的演算法,以空間複雜度換時間複雜度,能輸出1到2350000的所有質數,之後的會因為第三行填充陣列消耗太多記憶體而不能進行其他運算(128m),但是執行效率比演算法1最後優化的要快很多。

這裡主要對比演算法1最後優化的演算法和演算法3

設定time_limit為無限,記憶體為10gb。

以下列簡單**粗略計算時間

<?php

$starttime

=time()

;include

('primes/primes2.php');

//include('primes/primes3.php');

為演算法1最後優化演算法

為演算法3

$endtime

=time()

;$processtime

=$endtime

-$starttime

;echo

$processtime

;

輸出1到10000000的質數(畢竟戰鬥才是男人的浪漫!):

演算法1消耗時間(輸出的processtime):138s

演算法3消耗時間(輸出的processtime):10s

輸出1到1000之間的所有素數

題目 輸出1到1000之間的所有素數 質數 prime number 又稱素數,有無限個。質數定義為在大於1的自然數中,除了1和它本身以外不再有其他因數,這樣的數稱為質數。思路 偶數肯定不是素數,所以遞增的時候可以以奇數的形式遞增,再在奇數中去掉非質數的數。1 include2 3using nam...

輸出n以內的所有素數(質數)

素數 質數 除能被自己和1整除,不能被其他數整除的數叫素數,1和0既非素數也非合數。素數一定是不能整除2和3,但不能整除2和3的不一定是素數如35和49 def odd iter n liste i for i in range 2,n 1 k 0while k思路分析 1 先生成3開頭的奇數,因為...

輸出1到n中所有的素數

思路 判斷乙個數n是否為素數,分別將2到 根號n 即根號n取整 作為除數,若都不整除,則n為素數。第一次 include include include 找出1到n內所有素數.c written by chen gengru updated on 2018 11 2 intmain if j 0 r...