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 相关文章推荐
javascript CSS画图之基础篇
Jul 29 Javascript
使用JQUERY Tabs插件宿主IFRAMES
Jan 01 Javascript
JS图片浏览组件PhotoLook的公开属性方法介绍和进阶实例代码
Nov 09 Javascript
js页面跳转的常用方法整理
Oct 18 Javascript
javascript中全局对象的parseInt()方法使用介绍
Dec 19 Javascript
javascript获取本机操作系统类型的方法
Aug 13 Javascript
JS onkeypress兼容性写法详解
Apr 27 Javascript
requireJS使用指南
Apr 27 Javascript
把普通对象转换成json格式的对象的简单实例
Jul 04 Javascript
浅谈js中StringBuffer类的实现方法及使用
Sep 02 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
Mar 07 Javascript
微信小程序实现渐入渐出动画效果
Jun 13 Javascript
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正则匹配汉字的方法介绍
2013/04/25 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
执行iframe中的javascript方法
2008/10/07 Javascript
自己写了一个展开和收起的多更能型的js效果
2013/03/05 Javascript
JS使用ajax方法获取指定url的head信息中指定字段值的方法
2015/03/24 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
2015/07/27 Javascript
js中的eval()函数把含有转义字符的字符串转换成Object对象的方法
2016/12/02 Javascript
原生js实现键盘控制div移动且解决停顿问题
2016/12/05 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
JS通过调用微信API实现微信支付功能的方法示例
2017/06/29 Javascript
jqgrid实现简单的单行编辑功能
2017/09/30 Javascript
Angular自定义组件实现数据双向数据绑定的实例
2017/12/11 Javascript
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
2018/03/14 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
2019/12/20 Javascript
python采集博客中上传的QQ截图文件
2014/07/18 Python
Python中遇到的小问题及解决方法汇总
2017/01/11 Python
python基础教程之五种数据类型详解
2017/01/12 Python
总结python中pass的作用
2019/02/27 Python
Python实现SMTP邮件发送
2020/06/16 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
python3爬虫中多线程的优势总结
2020/11/24 Python
HTML5的语法变化介绍
2013/08/13 HTML / CSS
鼠标滚轮事件和Mac触控板双指事件
2019/12/23 HTML / CSS
金山毒霸系列的笔试题
2013/04/13 面试题
七匹狼男装广告词
2014/03/21 职场文书
趣味运动会策划方案
2014/06/02 职场文书
公司踏青活动方案
2014/08/16 职场文书
教师竞聘上岗演讲稿
2014/09/03 职场文书
2014年教师个人工作总结
2014/11/10 职场文书
2015国庆节66周年标语
2015/07/30 职场文书
公务员爱岗敬业心得体会
2016/01/25 职场文书
八年级历史教学反思
2016/02/19 职场文书
Go timer如何调度
2021/06/09 Golang
Python机器学习之底层实现KNN
2021/06/20 Python
Mac电脑OS系统下安装Nginx的详细教程
2022/04/14 Servers