我查了一下,这个模式是Hofstadter Female sequence。方程是:
M(n)= n-F(M(n-1))
F(n)= n-M(F(n-1))
但我不确定如何将其纳入代码。
到目前为止,我有:
while () {
_p++
_r++
if (_p % 2 === 0) {
_r = _p - 1;
}
}
任何帮助?
答案 0 :(得分:5)
没有memoization:
function F(n)
{
return 0 < n ? n - M(F(n-1)) : 1
}
function M(n)
{
return 0 < n ? n - F(M(n-1)) : 0
}
var N = 10;
var f = [];
var m = [];
for (var i = 0; i <= N; ++i) {
f.push(F(i));
m.push(M(i));
}
console.log('F: ' + f.join(','))
console.log('M: ' + m.join(','))
输出:
F: 1,1,2,2,3,3,4,5,5,6,6
M: 0,0,1,2,2,3,4,4,5,6,6
答案 1 :(得分:3)
如果可能,应该避免递归,这样您就可以缓存 F(n)和 M(n)的已计算值:
var f = new Array();
var m = new Array();
function F(n){
if(f[n] != undefined) {
return f[n];
}
if (n==0) {
value = 1;
} else {
value = n - M(F(n-1));
}
f[n] = value;
return value;
}
function M(n){
if(m[n] != undefined) {
return m[n];
}
if (n==0) {
value = 0;
} else {
value = n - F(M(n-1));
}
m[n] = value;
return value;
}
对于更大的数字(尝试使用10000),这会产生更快的结果
答案 2 :(得分:2)
怎么样:
function F(n){
if (n==0) return 1
else return n - M(F(n-1))
}
function M(n){
if (n==0) return 0
else return n - F(M(n-1))
}
var str = ""
for(var i=0; i<=10; i++) str += F(i) + ", "
console.log(str.substr(0,str.length-2))
答案 3 :(得分:2)
与GaborSch's answer类似,您可以使用Doug Crockford's memoizer
函数,该函数可在 Javascript: The Good Parts的第4章中找到。使用memoization男性和女性Hofstadter序列的前150个术语的计算时间低至256毫秒,相比之下几乎没有记忆的8秒。
var memoizer = function (memo, formula) {
var recur = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = formula(recur, n);
memo[n] = result;
}
return result;
};
return recur;
};
var maleHofstadter = memoizer([0], function (recur, n) {
return n - femaleHofstadter(recur(n-1));
});
var femaleHofstadter = memoizer([1], function (recur, n) {
return n - maleHofstadter(recur(n-1));
});
var N = 150;
var f = [];
var m = [];
for (var i = 0; i <= N; ++i) {
f.push(femaleHofstadter(i));
m.push(maleHofstadter(i));
}
console.log('F: ' + f.join(','));
console.log('M: ' + m.join(','));