我有一个记忆功能,它将记忆返回一个总和的递归函数,例如Number,但是我的collatz函数却不返回一个数组。备忘录功能中的我的地图将具有不同的键,但具有相同的值,并且不会记忆该功能的每个步骤。我正在尝试使其尽可能地组合。
控制台在collatz中记录日志以检查它是否已运行将按预期第一次注销。
我已经在指数递归函数中对此进行了测试,并使用了另一个可以正确记忆的键盘生成器函数。
const memoized = (fn, keymaker = JSON.stringify) => {
const lookupTable = new Map();
return function (...args) {
const key = keymaker.call(this, args);
return lookupTable[key] || (lookupTable[key] = fn.apply(this, args));
}
};
const ignoreOthers = ([...values])=>{
return JSON.stringify(values.shift())
}
const memCollatz = memoized((n,arr=[]) =>{
//console.log('ran')
if (n<=1) return arr.concat(1)
else if(n %2 === 0) return memCollatz(n / 2,arr.concat(n))
else return memCollatz((n*3)+1,arr.concat(n))
},ignoreOthers)
console.log(memCollatz(5))
console.log(memCollatz(6))
console.log(memCollatz(6))
/*
Map {
'1': [ 5, 16, 8, 4, 2, 1 ],
'2': [ 5, 16, 8, 4, 2, 1 ],
'3': [ 5, 16, 8, 4, 2, 1 ],
'4': [ 5, 16, 8, 4, 2, 1 ],
'5': [ 5, 16, 8, 4, 2, 1 ],
'6': [ 5, 16, 8, 4, 2, 1 ],
'8': [ 5, 16, 8, 4, 2, 1 ],
'10': [ 5, 16, 8, 4, 2, 1 ],
'16': [ 5, 16, 8, 4, 2, 1 ] }
*/
运行上述控制台日志后,这就是我的地图,但是应该以n
作为键并记住每个步骤。
答案 0 :(得分:0)
由于您在memCollatz中构建arr
的方式,代码执行将如下所示:
memCollatz(5) | arr = [] | map is empty
memCollatz(16) | arr = [5] | map is empty
memCollatz(8) | arr = [5, 16] | map is empty
memCollatz(4) | arr = [5, 16, 8] | map is empty
memCollatz(2) | arr = [5, 16, 8, 4] | map is empty
memCollatz(1) | arr = [5, 16, 8, 4, 2] | map is empty
对memCollatz(1)的最后一次调用是第一个实际返回内容的调用,因此
{1: [5, 16, 8, 4, 2, 1]}
已添加到查找图
现在,因为memCollatz(2)仅返回了返回的任何memCollatz(1),所以另一个 条目
{2: [5, 16, 8, 4, 2, 1]}
已添加到地图
同样,因为memCollatz(4)仅返回了返回的任何memCollatz(2),所以另一个条目
{4: [5, 16, 8, 4, 2, 1]}
已添加到地图
...等等。
要解决此问题,您需要避免这种“直通”行为,即确保memCollatz(1)返回与memCollatz(2)不同的内容,等等。
这是一个例子:
const memCollatz = memoized((n) =>{
if (n<=1) return [1];
else if(n %2 === 0) return [n].concat(memCollatz(n / 2))
else return [n].concat(memCollatz((n*3)+1))
},ignoreOthers)