1到100,怎么找出里面的2,5,8,11,14...这种数出来?引起的栈堆溢出问题
发布于 2022年 01月 22日 21:31
今天在群里有小伙伴问,1到100,怎么找出里面的2,5,8,11,14...这种数?
第一反应是找规律,上一个数+3, 基于for循环的基础上,最后确定规律为3n-1 n=i+1
代码如下:
const getNumSet = () => {
const arr = [];
for (let i=0;i<100;i+=1){
const n = i+1;
if (3*n-1<=100){
arr.push(3*n-1)
}
}
return arr
}
后来想到还可以用递归去做,所以又写了一种递归的写法
代码如下:
const getNumSet1 = () => {
const arr = [];
const fact = num => num<= 2 ? 2 : fact(num-1)+3;
for (let i=2;i<100;i+=1){
if (fact(i)<=100){
arr.push(fact(i))
}
}
return arr
}
两种方法都实现了一样的效果,但是,当数据量过大的时候,递归写法会导致 RangeError: Maximum call stack size exceeded
报错. 也就是所谓的栈堆溢出;
解决方法如下:
const getNumSet1 = () => {
const arr = [];
const fact = num =>{
if (num===2){
return 2
}
return (()=>fact(num-1)+3)() // 给一个内部函数
}
for (let i=2;i<100000;i+=1){
if (fact(i)<=100000){
arr.push(fact(i))
}
}
return arr
}
但是! 但是! 但是! 递归处理10W条数据,递归需要的时间远远大于第一种方法
关于递归栈堆溢出,有兴趣的可以看看 栈堆溢出解决办法: juejin.cn/post/684490… JavaScript 中arguments.callee的代替用法:blog.csdn.net/qq_17550381…
如有其它更简单更高效的写法 欢迎各位留下您的想法