递归检查一系列操作是否产生给定的数字

时间:2018-05-27 12:53:42

标签: javascript recursion

在递归部分的Eloquent JS一书中,给出了一个程序:

  

考虑这个难题:从数字1开始并反复出现   添加5或乘以3,无限量的新数字   可以生产。你会怎么写一个函数,给定一个数字,   试图找到一系列这样的加法和乘法   产生那个数字?例如,数字13可以通过   首先乘以3,然后再加5,然后加15   根本无法达到。

我有以下程序看起来像检查它,但我不知道如何打印它序列。

function tester (value, key) {
    if (value == key) {
        return 1;
    }

    else if (value > key) {
        return 0;
    }

    else {
        if ( tester(value+5, key) || tester(value*3, key) ) {
            return 1;
        }
        return 0;
    }
}

2 个答案:

答案 0 :(得分:2)

您可以存储序列,如果找到,计算将返回序列。

function tester(key, value = 1, sequence = value) {
    if (value > key) {
        return false;
    }

    if (value === key) {
        return sequence;
    }

    return tester(key, value + 5, '(' + sequence + ' + 5)')
        || tester(key, value * 3, sequence + ' * 3');
}

console.log(tester(15));
console.log(tester(11));
console.log(tester(24));
console.log(tester(37));

答案 1 :(得分:2)

您的版本对我来说有点奇怪,返回10而不是truefalse。你是否习惯于将布尔与这种整数混淆的语言?但它看起来应该有效。

我会用不同的方式写出来。我通常更喜欢我的递归计数到较小的输入。您可以编写一个简单的函数来测试这样的值:



const m3a5 = (n) => n < 1 
  ? false 
  : n == 1
    ? true
    : m3a5(n - 5) || (n % 3 === 0 && m3a5(n / 3))

console.log(m3a5(13)) //=> true
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> true
&#13;
&#13;
&#13;

这应该完全等同于你的,模数为布尔/ int差异。

有了这个,您可以以相当简单的方式扩展它,以便您捕获步骤:

&#13;
&#13;
const m3a5 = (n, steps = []) => n < 1 
  ? false 
  : n == 1 
    ? steps
    : m3a5(n - 5, ['+5'].concat(steps)) 
      || (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))

console.log(m3a5(13)) //=> ['*3', '+5', '+5']
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> ['*3', '+5, '+5', '+5']
&#13;
&#13;
&#13;

请注意,这将显示一条可能的路径,而不是所有路径。例如['+5', '*3']m3a5(18)的另一种可能结果,您可以通过将主分支切换到

来获得结果。
: (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps))) 
  || m3a5(n - 5, ['+5'].concat(steps))

但如果您想要所有路径,那么代码就会大不相同。