JavaScript判斷數(shù)字是否為質(zhì)數(shù)的方法匯總
前言
今天看到一個(gè)題目,讓判斷一個(gè)數(shù)字是否為質(zhì)數(shù).看上去好像不難.因此,我決定實(shí)現(xiàn)一下.
DOM結(jié)構(gòu)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計(jì)算500以內(nèi)的質(zhì)數(shù)并輸出</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div class="echo">
<input type="text" id="num" value="">
<input type="button" id="submit" value="提交">
</div>
</body>
</html>
<script>
$(function(){
$("#submit").on('click',function(){
var num = $("#num").val();
if (isPrimeNum(num)) {
alert(num+"是質(zhì)數(shù)");
}else{
alert(num+"是合數(shù)");
}
});
});
</script>
如上所示,我們通過(guò) isPrimeNum(num) 函數(shù),來(lái)實(shí)現(xiàn)判斷是否為質(zhì)數(shù).下面我們來(lái)實(shí)現(xiàn)這個(gè)函數(shù).
通過(guò)FOR循環(huán)來(lái)判斷是否為質(zhì)數(shù)
function isPrimeNum(num){
for (var i = 2; i < num; i++) {
if (num%i==0){
return false;
}
};
return true;
}
原理比較簡(jiǎn)單,通過(guò)2以上的數(shù)字不斷和目標(biāo)數(shù)字求余數(shù),如果能得到0,就表示這是一個(gè)合數(shù)而不是質(zhì)數(shù).
不過(guò)這個(gè)運(yùn)算量好像有點(diǎn)大
優(yōu)化一下第一個(gè)方法
很簡(jiǎn)單嘛,一下子就實(shí)現(xiàn)了.但是,好像可以優(yōu)化一下.我們好像不必一直追到這個(gè)數(shù)字去求余數(shù),我們好像只需要循環(huán)到這個(gè)數(shù)的一半,就可以計(jì)算出來(lái)這個(gè)數(shù)字是不是質(zhì)數(shù)了.
function isPrimeNum(num){
for (var i = 2; i < num/2+1; i++) {
if (num%i==0){
return false;
}
};
return true;
}
經(jīng)過(guò)實(shí)測(cè),速度確實(shí)大為提升,但是,我知道,數(shù)字尾數(shù)為雙數(shù),或者為5,那么肯定不是質(zhì)數(shù),因此沒必要去計(jì)算.我們?cè)賮?lái)優(yōu)化一下
不計(jì)算數(shù)字尾數(shù)為雙數(shù)或者5的數(shù)字
function isPrimeNum(num){
if (!isDual(num)){
return false;
}
for (var i = 2; i < num/2+1; i++) {
if (num%i==0){
return false;
}
};
return true;
}
function isDual(num){
var num = num.toString();
var lastNum = num.substring(num.length-1,num.length);
return lastNum%2 == 0 || lastNum%5 == 0 ? false : true;
}
通過(guò)這樣的優(yōu)化,我們可以再減小運(yùn)算量了,至少減少一大半數(shù)字哦.(但是實(shí)測(cè)提升性能一般,因?yàn)檫@樣的數(shù)字,能夠很快的判斷出來(lái)不是質(zhì)數(shù))
這里substring()函數(shù)發(fā)現(xiàn),不能用在數(shù)字上,只能用在字符串上.悲催,因此先把數(shù)字變成了字符串.
如果不是數(shù)字或者整數(shù)的處理
如果用戶輸入的不是數(shù)字,或者是一個(gè)小數(shù),怎么辦呢?我迅速的寫了兩個(gè)方法來(lái)進(jìn)行處理…
function isPrimeNum(num){
if (!isNum(num)){
return false;
}
if (!isInteger(num)){
return false;
}
if (!isDual(num)){
return false;
}
for (var i = 2; i < num/2+1; i++) {
if (num%i==0){
return false;
}
};
return true;
}
function isInteger(num){
return num == ~~num ? true : false;
}
function isNum(num){
return num == +num ? true : false;
}
function isDual(num){
var num = num.toString();
var lastNum = num.substring(num.length-1,num.length);
return lastNum%2 == 0 || lastNum%5 == 0 ? false : true;
}
這里用了兩個(gè)小技巧,一個(gè)是小數(shù)取整~~num,一個(gè)是字符串轉(zhuǎn)數(shù)字.+num.
了解更多請(qǐng)閱讀我之前的博文《javascript 學(xué)習(xí)小結(jié) JS裝逼技巧(一) by FungLeo》
這并沒有提高什么效能,只是免去了計(jì)算錯(cuò)誤輸入.我們?cè)傧胍幌?有沒有什么快速判斷不是質(zhì)數(shù)的方法呢?
去除能被3整除的數(shù)字不計(jì)算
function isPrimeNum(num){
if (!isNum(num)){
return false;
}
if (!isInteger(num)){
return false;
}
if (num==2||num==3||num==5) {
return true;
}
if (!isDual(num)){
return false;
}
if (!isThree(num)){
return false;
}
for (var i = 2; i < num/5+1; i++) {
if (num%i==0){
return false;
}
};
return true;
}
function isInteger(num){
return num == ~~num ? true : false;
}
function isNum(num){
return num == +num ? true : false;
}
function isDual(num){
var num = num.toString();
var lastNum = num.substring(num.length-1,num.length);
return lastNum%2 == 0 || lastNum%5 == 0 ? false : true;
}
function isThree(num){
var str = num.toString();
var sum = 0;
for (var i = 0; i < str.length; i++) {
sum += +str.substring(i,i+1);
};
return sum%3 == 0 ? false : true;
}
這里,我們先把數(shù)字變成字符串,然后把字符串每一位都分拆出來(lái),并且相加求和,拿結(jié)果和3求余,就能得出這個(gè)數(shù)字是否能被3整除了.
哈哈我真聰明…實(shí)測(cè)性能貌似并沒有提高很多,但確實(shí)提高了一些的.有點(diǎn)小郁悶
但是,如果排除了3整除的數(shù)字,那么,我們就完全沒必要計(jì)算到一半啦,我們完全沒必要計(jì)算到一半,只需要計(jì)算到三分之一就好啦.另外,我們也排除了5,那么只要計(jì)算到五分之一就好啦….
迅速調(diào)整后,果然效率大大提升啊!!!!我威武…
但是,這樣在 2\3\5 三個(gè)質(zhì)數(shù),代碼會(huì)判斷是合數(shù),所以,需要再補(bǔ)上一句
if (num==2||num==3||num==5) {return true;}
別人的方法
然后我就想不到優(yōu)化的方法啦…于是,我就搜索了一下,找到下面的解決方法,我驚呆了!!!!!
function isPrimeNum2(num){
return !/^.?$|^(..+?)\1+$/.test(Array(num + 1).join('1'))
}
使用的是正則的方法,果然是簡(jiǎn)短啊,但是我毛線也看看懂呀!!!
我實(shí)在是搞不懂這是啥原理,我于是實(shí)測(cè)了一下,發(fā)現(xiàn),我的代碼效率遠(yuǎn)遠(yuǎn)高于這段代碼.由此可見,我的方法還是很優(yōu)秀的嘛!!
我的代碼打印100000以內(nèi)的所有質(zhì)數(shù)需要1600ms 而這段代碼需要160000ms 也就是說(shuō),我的代碼只要百分之一的時(shí)間就可以了.
不過(guò),誰(shuí)能看懂這段代碼請(qǐng)幫我解釋一下….
補(bǔ)充
看了一些相關(guān)的資料,好像我上面用num/5的方式貌似不太好(結(jié)果并不是錯(cuò)誤的).有一個(gè)更好的方式,就是使用Math.sqrt(num)求平方根的方式.
我的代碼的測(cè)試結(jié)果如下

如上圖所示,我的代碼的計(jì)算結(jié)果是完全正確的哦.但是用時(shí)是1638毫秒.經(jīng)過(guò)多次測(cè)試依然是這樣.
求平方根方式測(cè)試結(jié)果如下

如上圖所示,用這個(gè)方式更加科學(xué),速度更快,多次測(cè)試,用時(shí)在1150毫秒到1250毫秒之間.相比我的代碼性能提升大約25%.
我又是判斷位數(shù)是否是雙數(shù)或者5的,又是判斷加起來(lái)能不能被3整除的,折騰半天.我肯定是期望減少運(yùn)算量的.但是這些代碼本身也是有運(yùn)算量的.我把我的代碼都去除掉之后再看下

性能又得到了提升啊,看來(lái)我的那些計(jì)算全部都是負(fù)優(yōu)化啊!
最終,代碼如下:
function isPrimeNum(num){
if (!isNum(num)){
return false;
}
if (!isInteger(num)){
return false;
}
for (var i = 2; i <= Math.sqrt(num); i++) {
if (num%i==0){
return false;
}
};
return true;
}
function isInteger(num){
return num == ~~num ? true : false;
}
function isNum(num){
return num == +num ? true : false;
}
小結(jié):完全是我算術(shù)不好導(dǎo)致我在前面各種自作聰明.不過(guò),練練小技巧也是好的-_-|||
最后看下計(jì)算100萬(wàn)以內(nèi)的所有質(zhì)數(shù)需要多長(zhǎng)時(shí)間

以上所述是小編給大家介紹的JavaScript判斷數(shù)字是否為質(zhì)數(shù)的方法匯總,希望對(duì)大家有所幫助.
相關(guān)文章
layui table checked獲取選中數(shù)據(jù)方式
這篇文章主要介紹了layui table checked獲取選中數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
JavaScript獲取頁(yè)面中表單(form)數(shù)量的方法
這篇文章主要介紹了JavaScript獲取頁(yè)面中表單(form)數(shù)量的方法,涉及javascript操作表單document.forms數(shù)組的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
javascript 自動(dòng)轉(zhuǎn)到命名錨記
javascript 自動(dòng)轉(zhuǎn)到命名錨記,方面業(yè)內(nèi)控制導(dǎo)航等信息2009-01-01
JavaScript實(shí)現(xiàn)與使用發(fā)布/訂閱模式詳解
這篇文章主要介紹了JavaScript實(shí)現(xiàn)與使用發(fā)布/訂閱模式,較為詳細(xì)的分析了發(fā)布/訂閱模式的概念、原理并結(jié)合實(shí)例形式分析了javascript實(shí)現(xiàn)與使用發(fā)布/訂閱模式的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
JavaScript的模塊化:封裝(閉包),繼承(原型) 介紹
在復(fù)雜的邏輯下, JavaScript 需要被模塊化,模塊需要封裝起來(lái),只留下供外界調(diào)用的接口。閉包是 JavaScript 中實(shí)現(xiàn)模塊封裝的關(guān)鍵,也是很多初學(xué)者難以理解的要點(diǎn)2013-07-07
JavaScript中高級(jí)語(yǔ)法??表達(dá)式用法示例詳解
這篇文章主要為大家介紹了JavaScript中高級(jí)語(yǔ)法??表達(dá)式用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04

