for循环数序列(1,1,2,2,3,3等)

时间:2014-02-06 18:17:12

标签: javascript loops math for-loop

我查了一下,这个模式是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;
    }
}

任何帮助?

4 个答案:

答案 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

http://jsfiddle.net/KtGBg/1/

答案 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(','));