繁体   English   中英

我们如何获得两次递归调用的最小值,一个是加法,另一个是减法?

[英]How could we get min of two recursive calls, one which adds, another which subtracts?

我们正在做这个编程练习:办公空间 #2 - 距离最近的三个 声明是:

你喜欢在办公室听音乐。

由于您的同事健谈,您经常需要更改耳机的音量,而您发现自己使用键盘上的 + 和 - 来这样做。 每次击键时,这些键将音量增加和减少 2。 只有一个问题 - 您更喜欢可被 3 整除的数字。

有时您的同事很吵,有时他们正在吃午饭或上班迟到 - 相应地调整音量!

编写一个函数,接收当前音量并输出您必须按键盘上的 - 或 + 键的次数,以使音量成为可被 3 整除的数字。

在这个存在平面上,音乐不能低于 0 音量。

例如:volume = 8 : output = 1(按 - 键会带你到 6,它可以被 3 整除,而不是按两次 + 键会得到 12)

我们编写了以下代码:

function musicalOCD(volume) {
  console.log("\n\nvolume: "+volume);
  if(volume%3==0) return 0;
  return Math.min(1+musicalOCD(volume+2),1+musicalOCD(volume-2));
}

然而,它仅通过基本案例测试,当体积可被 13 整除时。

如果我们传入其他卷,它会输出:

RangeError: Maximum call stack size exceeded
    at Socket.Readable.removeListener (_stream_readable.js:852:47)
    at write (console.js:172:12)
    at Console.log (console.js:200:3)
    at musicalOCD (test.js:5:11)
    at musicalOCD (test.js:7:21)

作为踪迹:

volume: 2


volume: 4


volume: 6


volume: 2


volume: 4


volume: 6

所以我们可以编写代码来进行递归调用,将值添加到音量:

function musicalOCD(volume) {
  console.log("\n\nvolume: "+volume);
  if(volume%3==0) return 0;
  return 1+musicalOCD(volume+2);
}

但是在以下测试中:

describe("Fixed tests", function() {
  const testing = (volume, exp) => it(`Testing for ${volume}`, () => assert.strictEqual(musicalOCD(volume), exp));
  testing(4, 1);
  testing(12, 0);
  testing(20, 1);
  testing(22, 1);
  testing(68, 1);
});

测试 20 和 68 将输出 2 而不是 1...

如果我们反过来做:

function musicalOCD(volume) {
  console.log("\n\nvolume: "+volume);
  if(volume%3==0) return 0;
  return 1+musicalOCD(volume-2);
}

然后测试 22 和 4 将输出 2 而不是 1 ...

我们如何将两个递归调用结合到一个通用答案中?

我们已阅读:

 const testing = (volume, exp) => { console.assert(musicalOCD(volume) === exp, 'Testing for ${volume} - failure'); }; testing(4, 1); testing(12, 0); testing(20, 1); testing(22, 1); testing(68, 1); console.log('Run tests - done'); function musicalOCD(volume) { return Math.min( // <------- will return min value of two tests _musicalOCD(volume, +2), _musicalOCD(volume, -2) ); } function _musicalOCD(volume, mod) { if (volume < 0) return 0; if (volume >= 100) return 0; //console.log("\\n\\nvolume: " + volume); if (volume % 3 == 0) return 0; return 1 + _musicalOCD(volume + mod, mod); }

您可以使用一种方法,通过测试递减forst然后递增来分叉递归调用。

 function musicalOCD(volume) { if (volume % 3 === 0) return 0; return 1 + (musicalOCD(volume - 2) && musicalOCD(volume + 2)); } [[4, 1], [12, 0], [20, 1], [22, 1], [68, 1]].forEach(([v, r]) => console.log(v, musicalOCD(v), r));

带有测试说明。

 function musicalOCD(volume, dir) { console.log(dir); if (volume % 3 === 0) return 0; return 1 + (musicalOCD(volume - 2, 'down') && musicalOCD(volume + 2, 'up')); } [[4, 1], [12, 0], [20, 1], [22, 1], [68, 1]].forEach(([v, r]) => console.log(v, musicalOCD(v), r));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM