Javascript-更好地替代递归调用

Javascript-更好地替代递归调用,javascript,performance,recursion,optimization,Javascript,Performance,Recursion,Optimization,我有以下问题。 我需要根据时间t计算一个数字x,x将表示为M(t)。 我们有以下几点 M(0)=1 M(1)=1 M(2)=2 M(2t)=M(t)+M(t+1)+t(对于t>1) M(2t+1)=M(t-1)+M(t)+1(对于t>=1) 说到这里,我想到的实现这个的第一件事就是使用递归 function CalculateForTime(t) { if (t == 0 || t == 1) { return 1; } else if (t == 2

我有以下问题。 我需要根据时间t计算一个数字x,x将表示为M(t)。 我们有以下几点

  • M(0)=1
  • M(1)=1
  • M(2)=2
  • M(2t)=M(t)+M(t+1)+t(对于t>1)
  • M(2t+1)=M(t-1)+M(t)+1(对于t>=1)
说到这里,我想到的实现这个的第一件事就是使用递归

function CalculateForTime(t) {
    if (t == 0 || t == 1) {
        return 1;
    }
    else if (t == 2) {
        return 2;
    }
    else if (t % 2 == 0) {
        t = t / 2;
        return CalculateForTime(t) + CalculateForTime(t + 1) + t;
    }
    else {
        t = (t - 1) / 2;
        return CalculateForTime(t - 1) + CalculateForTime(t) + 1;
    }
}
但在运行大量t(例如1^20)时,它会中断

我试着研究尾部调用递归或将递归方法替换为迭代方法,但没有真正弄明白

如果尾部递归或迭代是一种方式,那么请我需要有关转换的帮助。如果不是的话,我愿意用不同的方法来优化它

谢谢,,
Omar。

您可以将值存储在一个数组中,这样就不需要重新计算

var时间=[1,1,2];
函数计算时间(t){
t=数学楼层(t/2);
返回时间[t]| |(时间[t]=计算时间(t)+计算时间(t+1)+t);
}
console.log(
计算时间(100),
计算时间(1000),
计算时间(10000),
);

console.log(times.slice(0100))您可以使用哈希表,因为对于数组,它将生成没有值的孔

函数计算时间(t){
var k=t;
if(查找中的k){
返回查找[k];
}
如果(t==0 | | t==1){
返回查找[k]=1;
}
如果(t==2){
返回查找[k]=2;
}
如果(t%2==0){
t=t/2;
返回查找[k]=calculateForTime(t)+calculateForTime(t+1)+t;
}
t=(t-1)/2;
返回查找[k]=calculateForTime(t-1)+calculateForTime(t)+1;
}
var查找={};
console.log(calculateForTime(1e10))

.as console wrapper{max height:100%!important;top:0;}
您可以使用备忘录来避免反复重新计算相同的值。看

这与其他人的建议相同,只是它将算法与值缓存分离

function memoize(func){ 
    var cache = {}; 
    return function( arg ){ 
         if(arg in cache) {
             return cache[arg]; 
         } else { 
             return cache[arg] = func( arg );
         } 
     }
  }

  // Overwrite with a function that remember previous results
  CalculateForTime = memoize(CalculateForTime);

请原谅任何打字错误,在电话中回答。

这样做之后,OP应该查看一个记忆装饰器,以隐藏算法中缓存的细节