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…

如有其它更简单更高效的写法 欢迎各位留下您的想法

推荐文章