在递归部分的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;
}
}
答案 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)
您的版本对我来说有点奇怪,返回1
或0
而不是true
或false
。你是否习惯于将布尔与这种整数混淆的语言?但它看起来应该有效。
我会用不同的方式写出来。我通常更喜欢我的递归计数到较小的输入。您可以编写一个简单的函数来测试这样的值:
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;
这应该完全等同于你的,模数为布尔/ int差异。
有了这个,您可以以相当简单的方式扩展它,以便您捕获步骤:
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;
请注意,这将显示一条可能的路径,而不是所有路径。例如['+5', '*3']
是m3a5(18)
的另一种可能结果,您可以通过将主分支切换到
: (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
|| m3a5(n - 5, ['+5'].concat(steps))
但如果您想要所有路径,那么代码就会大不相同。