判斷一個數(shù)是否是質(zhì)數(shù)
創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、鶴崗網(wǎng)絡(luò)推廣、微信平臺小程序開發(fā)、鶴崗網(wǎng)絡(luò)營銷、鶴崗企業(yè)策劃、鶴崗品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供鶴崗建站搭建服務(wù),24小時服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
最暴力的解法
利用質(zhì)數(shù)的性質(zhì):設(shè)i為質(zhì)數(shù),則i只能被 1 和 i整除。
因此對于i,我們可以令 2..i-1 依次除以i,如果均不能被整除,則說明是質(zhì)數(shù)。
代碼如下
private static boolean isPrime1(int nr) {
for (int i = 2; i nr; i++) {
if (nr % i == 0) return false;
}
return true;
}123456123456
稍微暴力的方法
同樣利用其性質(zhì),但我們可以注意到,當(dāng) x i / 2 時,則 x 肯定不能被 i 整除。
對于i,我們可以令 2..x 依次除以i,其中x為sqrt(i)
代碼如下
private static boolean isPrime2(int nr) {
for (int i = 2; i*i = nr; i++) {
if (nr % i == 0) return false;
}
return true;
}123456123456
效率更高的算法
提供一個數(shù)組 nums = {2, 3, 4, 5,... 17}
我們知道 nums[0] 為質(zhì)數(shù),將nums中所有能被nums[0]整除的數(shù)移除,此時數(shù)組為 nus = {2, 3, 5, 7, 9, 11, 13, 15, 17}
接著將所有能被 3 整除的數(shù)移除。此時為 nums = {2, 3, 5, 7, 11, 13, 17}
接下來的數(shù)是 5,因為 5*5 17,所以移除過程結(jié)束。此時的nums值為輸入nums中的所有素數(shù)。
上面的步驟之所以正確是因為:合數(shù)必定可以由質(zhì)數(shù)相乘得到,則對任意質(zhì)數(shù)i,如跡謹(jǐn)運(yùn)果其不能被sqrt(i)前的所有質(zhì)數(shù)整除,則其必定為質(zhì)數(shù)晌旦(小于 sqrt(i) 的合數(shù)必定可以被小于 sqrt(i) 的質(zhì)數(shù)合成)。
代碼如下
private static void primeList(ListInteger nums) {
for (int i = 0; i nums.size(); i++) {
if (nums.get(i)*nums.get(i) = nums.get(nums.size()-1)) {
for (int j = i+1; j nums.size(); j++) {
if (nums.get(j) % nums.get(i) == 0) nums.remove(j);
}
} else {
return ;
}
}
}12345678910111234567891011
此算法存在的問題也很明顯,說它是判斷一個數(shù)是否是質(zhì)數(shù)獲取不太準(zhǔn)確,其作用應(yīng)該是 “打印出小于等于某值的所有質(zhì)數(shù)”
使用素數(shù)表
上面的算法有一個缺陷,它對輸入數(shù)組要求較高,要求包含了數(shù)組最大值之前的所有素數(shù),且是已排序的。也就是說它不能用來直接判斷一個數(shù)是否是素數(shù)。
通常情況下,我們會使用一個姿梁素數(shù)表。接著用來整除的元素便可以從這個素數(shù)表中獲取
這種算法的局限在于素數(shù)表是有限的,對于超出素數(shù)表最大值平方的數(shù)則需要加上上述方法二的步驟才能判斷(盡管這種情況不多)。
算法實(shí)現(xiàn)同上,只是此時直接從素數(shù)表獲取素數(shù)即可
;fps=1
function?selectnum($num){
for?($j?=?2;?$j??sqrt($num);?$j++)?{
仿陸?????if?($num?%?$j?==?0)?{
return?false;
}
}
return?true;
}
判斷是不是 素數(shù) ,若 返回true 就是 素數(shù),因為 若一個數(shù)能被整除,那肯定就不是素數(shù)!?。?/p>
加平方根驗證(sqrt)的目的,是為了優(yōu)化性能,因為:
如果它不是質(zhì)數(shù),那么它應(yīng)該可以表示成兩個非1非自身的數(shù)相乘。
而這兩個數(shù),必然有一個大于平方根一個小于平方根,或者兩個都等于平方根。
下面是 獲取 1000000 內(nèi) 所有的 素數(shù) ,在PHP7下 能做到2.3秒,? 在5下 不到4秒!
public?function?test()
{
$start_time?=?microtime(true);
set_time_limit(0);
$num_max?=?1000000;
$arr?=?[]?;
裂橋for?($i?=?1;($i*6)?=?$num_max;?$i++)?{
$base=$i*6;
$num=$base-1;
$sta=$this-testnum($num);
if?($sta)?{
$arr[$num]=1;
}
$num=$base+1;
$sta=$this-testnum($num);
if?($sta)?{
$arr[$num]=1;
}
}
$end?=?microtime(true);
$zong?=?$end?-$start_time;
echo?'開始'?.?$start_time?.?'br/'?;
echo?'結(jié)束'?.?$end?.?'br/'?;
echo?'用時'?.?$zong??.?'br/';
echo?'共'?.?count($arr)?.?'個素數(shù)';
}
function?testnum($num){
for?($j?=?2;?$j??sqrt($num);?$j++)?{
if?($num?%?$j?==?0)?{
return?肆大猛false;
}
}
return?true;
}