10万以内快乐数之和

5 篇文章 1 订阅
3 篇文章 0 订阅

首先快乐数定义:快乐数(happy number)有以下的特性:在给定的进位制下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必定为1。

如:28 ---> 2*2+8*8=68 ---> 6*6+8*8=100 ---> 1*1+0*0+0*0=1,因此28和68还有100都是快乐数

十万以内快乐数之和(直接上代码):

方法1:

直接复制粘贴在html文档就能跑起来,具体实现原理请看代码注释!

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>10万以内快乐数之和</title>
	</head>
	<body>
		10万以内快乐数之和:<strong class="num"></strong>
		<script src="./jQuery_v2.1.4.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var cacheArr = []	//缓存数据
			var isHappyNumArr = [] //快乐数
			var noHappyNumArr = [] //非快乐数
			// 判定是否为快乐数
			var ifHappyNum = function(data){
				var data = data.toString()
				// 如果是快乐数,就把数据放到快乐数arr,清空缓存数据,返回true
				if(isHappyNumArr.indexOf(data)>-1){
					isHappyNumArr.push(...cacheArr)
					cacheArr = []
					return true
				}
				// 如果不是快乐数,就把数据放到非快乐数arr,清空缓存数据,返回false
				if(noHappyNumArr.indexOf(data)>-1){
					noHappyNumArr.push(...cacheArr)
					cacheArr = []
					return false
				}
				// 把每一个计算的数据都放置到缓存当中
				cacheArr.push(data)
				if(data === '0') return 0
				var num = 0
				// 计算
				for(var i=0; i<data.length; i++){
					var item = data[i]
					num += item*item
				}
				// 快乐数,缓存中所有都数据都是快乐数
				if(num === 1){
					isHappyNumArr.push(...cacheArr)
					cacheArr = []
					return true
				}
				//形成闭环表示非快乐数,缓存中所有数据都不是快乐数
				if(cacheArr.indexOf(''+num)>-1){
					noHappyNumArr.push(...cacheArr)
					cacheArr = []
					return false
				}
				// 没返回就递归调用
				return ifHappyNum(num)
			}
			for(var i=1; i<=100000; i++){
				ifHappyNum(i)
			}
			var Nummmmm = 0
			for(var j = 0; j<isHappyNumArr.length; j++){
				var item = isHappyNumArr[j]
				Nummmmm += Number(item)
			}
			console.log('isHappyNumArr===',isHappyNumArr)
			console.log('noHappyNumArr===',noHappyNumArr)
			console.log('Nummmmm===',Nummmmm)
			$('.num').text(Nummmmm)
		</script>
	</body>
</html>

此方法先存储两个快乐数和非快乐数都数组集合,然后后边传过来有需要判定的快乐数时就先进行对比,如果已经存储的快乐数集合里边已经有了,就直接返回不用再进行下边的计算判定了,数组当中没有的话就进行计算判定是否为快乐数,此方法大概15S才能跑出结果,因为后边的两个数组越来越大,因此对比是否存在时消耗了大量性能,很是鸡肋,因此我进行了优化版如下!

方法2:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>10万以内快乐数之和</title>
	</head>
	<body>
		10万以内快乐数之和:<strong class="num"></strong>
		<script src="./jQuery_v2.1.4.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var cacheArr = []	//缓存数据
			var isHappyNumArr = [] //快乐数
			var noHappyNumArr = [] //非快乐数
			var ifHappyNum = function(data){
				var data = data.toString()
				// 如果是快乐数,就把数据放到快乐数arr,清空缓存数据,返回true
				// if(isHappyNumArr.indexOf(data)>-1){
				// 	isHappyNumArr.push(...cacheArr)
				// 	cacheArr = []
				// 	return true
				// }
				// 如果不是快乐数,就把数据放到非快乐数arr,清空缓存数据,返回false
				// if(noHappyNumArr.indexOf(data)>-1){
				// 	noHappyNumArr.push(...cacheArr)
				// 	cacheArr = []
				// 	return false
				// }
				// 把每一个计算的数据都放置到缓存当中
				cacheArr.push(data)
				if(data === '0') return 0
				var num = 0
				// 计算
				for(var i=0; i<data.length; i++){
					var item = data[i]
					num += item*item
				}
				// 快乐数,缓存中所有都数据都是快乐数
				if(num === 1){
					isHappyNumArr.push(...cacheArr)
					cacheArr = []
					return true
				}
				//形成闭环表示非快乐数,缓存中所有数据都不是快乐数
				if(cacheArr.indexOf(''+num)>-1){
					noHappyNumArr.push(...cacheArr)
					cacheArr = []
					return false
				}
				// 没返回就递归调用
				return ifHappyNum(num)
			}
			var Nummmmm = 0
			for(var i=1; i<=100000; i++){
				if(ifHappyNum(i)){
					Nummmmm += i
				}
			}
			// var Nummmmm = 0
			// for(var j = 0; j<isHappyNumArr.length; j++){
			// 	var item = isHappyNumArr[j]
			// 	Nummmmm += Number(item)
			// }
			console.log('isHappyNumArr===',isHappyNumArr)
			console.log('noHappyNumArr===',noHappyNumArr)
			console.log('Nummmmm===',Nummmmm)
			$('.num').text(Nummmmm)
		</script>
	</body>
</html>

此方法实际上就是去掉了参数传进来时的一个indexOf判定,别的没有什么变化,但性能上有很大的提升,大概1S就能出结果。

以上为个人经验总结,如有异议欢迎留言沟通。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值