JavaScript判断数字是否为质数的方法汇总


Posted in Javascript onJune 02, 2016

前言

今天看到一个题目,让判断一个数字是否为质数.看上去好像不难.因此,我决定实现一下.

DOM结构

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算500以内的质数并输出</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+"是质数");
}else{
alert(num+"是合数");
}
});
});
</script>

如上所示,我们通过 isPrimeNum(num) 函数,来实现判断是否为质数.下面我们来实现这个函数.

通过FOR循环来判断是否为质数

function isPrimeNum(num){
for (var i = 2; i < num; i++) {
if (num%i==0){
return false;
}
};
return true;
}

原理比较简单,通过2以上的数字不断和目标数字求余数,如果能得到0,就表示这是一个合数而不是质数.

不过这个运算量好像有点大

优化一下第一个方法

很简单嘛,一下子就实现了.但是,好像可以优化一下.我们好像不必一直追到这个数字去求余数,我们好像只需要循环到这个数的一半,就可以计算出来这个数字是不是质数了.

function isPrimeNum(num){
for (var i = 2; i < num/2+1; i++) {
if (num%i==0){
return false;
}
};
return true;
}

经过实测,速度确实大为提升,但是,我知道,数字尾数为双数,或者为5,那么肯定不是质数,因此没必要去计算.我们再来优化一下

不计算数字尾数为双数或者5的数字

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;
}

通过这样的优化,我们可以再减小运算量了,至少减少一大半数字哦.(但是实测提升性能一般,因为这样的数字,能够很快的判断出来不是质数)

这里substring()函数发现,不能用在数字上,只能用在字符串上.悲催,因此先把数字变成了字符串.

如果不是数字或者整数的处理

如果用户输入的不是数字,或者是一个小数,怎么办呢?我迅速的写了两个方法来进行处理…

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;
}

这里用了两个小技巧,一个是小数取整~~num,一个是字符串转数字.+num.

了解更多请阅读我之前的博文《javascript 学习小结 JS装逼技巧(一) by FungLeo》

这并没有提高什么效能,只是免去了计算错误输入.我们再想一下,有没有什么快速判断不是质数的方法呢?

去除能被3整除的数字不计算

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;
}

这里,我们先把数字变成字符串,然后把字符串每一位都分拆出来,并且相加求和,拿结果和3求余,就能得出这个数字是否能被3整除了.

哈哈我真聪明…实测性能貌似并没有提高很多,但确实提高了一些的.有点小郁闷

但是,如果排除了3整除的数字,那么,我们就完全没必要计算到一半啦,我们完全没必要计算到一半,只需要计算到三分之一就好啦.另外,我们也排除了5,那么只要计算到五分之一就好啦….

迅速调整后,果然效率大大提升啊!!!!我威武…

但是,这样在 2\3\5 三个质数,代码会判断是合数,所以,需要再补上一句

if (num==2||num==3||num==5) {return true;}

别人的方法

然后我就想不到优化的方法啦…于是,我就搜索了一下,找到下面的解决方法,我惊呆了!!!!!

function isPrimeNum2(num){
return !/^.?$|^(..+?)\1+$/.test(Array(num + 1).join('1'))
}

使用的是正则的方法,果然是简短啊,但是我毛线也看看懂呀!!!

我实在是搞不懂这是啥原理,我于是实测了一下,发现,我的代码效率远远高于这段代码.由此可见,我的方法还是很优秀的嘛!!

我的代码打印100000以内的所有质数需要1600ms 而这段代码需要160000ms 也就是说,我的代码只要百分之一的时间就可以了.

不过,谁能看懂这段代码请帮我解释一下….

补充

看了一些相关的资料,好像我上面用num/5的方式貌似不太好(结果并不是错误的).有一个更好的方式,就是使用Math.sqrt(num)求平方根的方式.

我的代码的测试结果如下

JavaScript判断数字是否为质数的方法汇总

如上图所示,我的代码的计算结果是完全正确的哦.但是用时是1638毫秒.经过多次测试依然是这样.

求平方根方式测试结果如下

JavaScript判断数字是否为质数的方法汇总

如上图所示,用这个方式更加科学,速度更快,多次测试,用时在1150毫秒到1250毫秒之间.相比我的代码性能提升大约25%.

我又是判断位数是否是双数或者5的,又是判断加起来能不能被3整除的,折腾半天.我肯定是期望减少运算量的.但是这些代码本身也是有运算量的.我把我的代码都去除掉之后再看下

JavaScript判断数字是否为质数的方法汇总

性能又得到了提升啊,看来我的那些计算全部都是负优化啊!

最终,代码如下:

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;
}

小结:完全是我算术不好导致我在前面各种自作聪明.不过,练练小技巧也是好的-_-|||

最后看下计算100万以内的所有质数需要多长时间

JavaScript判断数字是否为质数的方法汇总

以上所述是小编给大家介绍的JavaScript判断数字是否为质数的方法汇总,希望对大家有所帮助.

Javascript 相关文章推荐
用window.location.href实现刷新另个框架页面
Mar 07 Javascript
一些经常会用到的Javascript检测函数
May 31 Javascript
javascript ajax 仿百度分页函数
Oct 29 Javascript
仿百度联盟对联广告实现代码
Aug 30 Javascript
上传图片预览JS脚本 Input file图片预览的实现示例
Oct 23 Javascript
新手快速学习JavaScript免费教程资源汇总
Jun 25 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
Jan 04 Javascript
js获取地址栏参数的两种方法
Jun 27 Javascript
vue项目中导入swiper插件的方法
Jan 30 Javascript
用vuex写了一个购物车H5页面的示例代码
Dec 04 Javascript
vue 中固定导航栏的实例代码
Nov 01 Javascript
jquery实现点击左右按钮切换图片
Jan 27 jQuery
Jquery on方法绑定事件后执行多次的解决方法
Jun 02 #Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 #Javascript
Javascript小技能总结(推荐)
Jun 02 #Javascript
Jquery为DIV添加click事件的简单实例
Jun 02 #Javascript
jquery中取消和绑定hover事件的实现代码
Jun 02 #Javascript
深入理解jQuery之事件移除
Jun 02 #Javascript
深入理解JQuery循环绑定事件
Jun 02 #Javascript
You might like
PHP与MySQL开发中页面出现乱码的一种解决方法
2007/07/29 PHP
php的ajax简单实例
2014/02/27 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
PHP实现的权重算法示例【可用于游戏根据权限来随机物品】
2019/02/15 PHP
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
jquery foreach使用示例
2013/09/12 Javascript
javascript引用赋值(地址传值)用法实例
2015/01/13 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
2016/03/07 Javascript
动态加载JavaScript文件的两种方法
2016/04/22 Javascript
jquery对象访问是什么及使用方法介绍
2016/05/03 Javascript
javaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序整理总结
2016/10/10 Javascript
Angular.JS利用ng-disabled属性和ng-model实现禁用button效果
2017/04/05 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
2017/09/12 Javascript
详解vue-cli项目中用json-sever搭建mock服务器
2017/11/02 Javascript
elementui的默认样式修改方法
2018/02/23 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
layui table 表格模板按钮的实例代码
2019/09/21 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
微信小程序通过websocket实时语音识别的实现代码
2020/08/19 Javascript
[42:39]老党炸弹人试玩视频
2014/09/03 DOTA
[01:16]DOTA2小知识课堂 Ep.03 芒果树无伤肉山
2019/12/05 DOTA
[15:07]lgd_OG_m2_BP
2019/09/10 DOTA
Python实现Linux中的du命令
2017/06/12 Python
Tensorflow的可视化工具Tensorboard的初步使用详解
2018/02/11 Python
Python3 实现爬取网站下所有URL方式
2020/01/16 Python
Pyecharts地图显示不完成问题解决方案
2020/05/11 Python
如何以Winsows Service方式运行JupyterLab
2020/08/30 Python
HTML5跳转小程序wx-open-launch-weapp的示例代码
2020/07/16 HTML / CSS
在线购买世界上最好的酒:BoozeBud
2018/06/07 全球购物
Mio Skincare英国官网:身体紧致及孕期身体护理
2018/08/19 全球购物
Radley英国官网:英国莱德利小狗包
2019/03/21 全球购物
党员承诺书怎么写
2014/05/20 职场文书
出国签证在职证明范本
2014/11/24 职场文书
建筑安全员岗位职责
2015/02/15 职场文书
公共场所卫生管理制度
2015/08/05 职场文书
总结Python变量的相关知识
2021/06/28 Python