素數是只能被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...