如何在电源回路使用递归日益增长的参数是多少?

问题描述 投票:4回答:4

这是一个典型的Power Loop problem,而我只需要一个简单而优雅(紧凑型)解决方案...我会一展拳脚的嵌套for循环问题/解决方案的样品。假设我需要这段代码转变成一个递归:

console.log("bits","Binary")
for (let i=0; i<2; i++) {
    show(i)
    for (let j=0; j<2; j++) {
      show(i,j)
      for (let k=0; k<2; k++)
        show(i,j,k) // ... l,m,n,o,p
  } // j
} // i

function show(...args) {
   let code = String( args.reduce( (ac,cur) => ''+ac+cur ) )
   console.log( code.length, code )
}

此3级样品的14-独特线输出是

bits Binary
1 '0'
2 '00'
3 '000'
3 '001'
2 '01'
3 '010'
3 '011'
1 '1'
2 '10'
3 '100'
3 '101'
2 '11'
3 '110'
3 '111'

难看和部分解

我试图用作为参考this solution解决:

callManyTimes([2,2,2], show);

function callManyTimes(maxIndices, func) {
    doCallManyTimes(maxIndices, func, [], 0);
}

function doCallManyTimes(maxIndices, func, args, index) {
    if (maxIndices.length == 0) {
        let x = args.slice(0); // cloning
        while(x.length>0) {
          func(x); // why send array[array]?
          x.shift();
        }
    } else {
        var rest = maxIndices.slice(1);
        for (args[index] = 0; args[index] < maxIndices[0]; ++args[index]) {
            doCallManyTimes(rest, func, args, index + 1);
        }
    }
}

function show(...args) {
   if (typeof args[0] == 'object') args=args[0] // workaround... can optimize?
   let code = String( args.reduce( (ac,cur) => ''+ac+cur ) )
   console.log( code.length, code )
}

输出有重复的线条,但也有是解决方案线的一个子集。所以,似乎附近,但丑陋的(不使用优雅复发栈等)

3 '000'
2 '00'
1 '0'
3 '001'
2 '01'
1 '1'
3 '010'
2 '10'
1 '0'
3 '011'
2 '11'
1 '1'
...
javascript recursion
4个回答
3
投票

你可以采取一个函数,该函数用于生成的值临时数组。

function show(...args) {
    let code = args.join('');
    console.log(code.length, code);
}

function callManyTimes(max, cb, items = []) {
    var i, temp;
    if (items.length === max.length) return;
    for (i = 0; i < max[items.length]; i++) {
        temp = items.concat(i);
        cb(...temp);
        callManyTimes(max, cb, temp);
    }
}

callManyTimes([2, 2, 2], show);

2
投票

一个简单的回溯递归函数将与像第一个例子中的顺序访问这些:

function iter(maxlength, cur = ''){
  if (cur.length >= maxlength) return
  for (let i = 0; i < 2; i++){
    console.log(cur.length + 1 + ":",   cur + i)
    iter(maxlength, cur + i)
  }
}

iter(3)

您也可以产生同样的想法和发电机功能(在这里它返回一个数组的数组后加盟,但同样的原理)数组:

function* iter(maxlength, prefix = []){
  if (prefix.length >= maxlength) return
   for (let i = 0; i < 2; i++){
     yield [i, ...prefix]
     yield * iter(maxlength, [i, ...prefix])
   }
}
  
console.log([...iter(3)].map(a => a.join(',')))

2
投票

我认为你正在寻找

callManyTimes([2,2,2], show);

function callManyTimes(maxIndices, func, args=[]) {
    if (maxIndices.length == 0) {
        func(...args);
    } else {
        func(...args);
        var rest = maxIndices.slice(1);
        var index = args.length;
        args = args.slice();
        for (args[index] = 0; args[index] < maxIndices[0]; ++args[index]) {
            callManyTimes(rest, func, args);
        }
    }
}

function show(...args) {
   let code = args.join(" ");
   console.log(args.length + ": "+ code )
}

而不是while循环的,你要调用func只有一次。要获取部分结果,你会放一个func调用与递归调用循环之前,就像你在你的扩展版本一样。我还取消了index参数,它仅仅是args.length,并添加一个新的水平之前进行args的副本。

此外,你应该只使用传播语法呼叫,当你在休息参数语法show收到的参数。


0
投票

您可以通过手写输出,并使用.repeat()

const f = (a,b,c=[a+b,b+a,a+b+a,a+a+b,a+b+b,b+a+b,b+b+a,b+a+a]) => {
  for(let i=3;i;c.push(a.repeat(i),b.repeat(i)),i--);return c
};

console.log(f('0','1'));
© www.soinside.com 2019 - 2024. All rights reserved.