首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我们怎么能得到两个递归调用的最小值,一个是加的,另一个是减的?

我们怎么能得到两个递归调用的最小值,一个是加的,另一个是减的?
EN

Stack Overflow用户
提问于 2020-03-22 10:13:30
回答 2查看 58关注 0票数 0

我们正在做这个编程练习:一个办公空间#2 -离Twos最近的三个。声明如下:

你喜欢在办公室听音乐。 你经常需要改变耳机的音量,这要归功于你健谈的同事,你发现自己是用键盘上的+和-来这样做的。按键每击一次,音量增加和减少2。只有一个问题--你更喜欢被3整除的数字。 有时你的同事很大声,而其他时候,他们在午餐或工作迟到-相应地调整音量! 编写一个函数,接收当前卷,并输出您必须按键盘上的-或+键的次数,以使音量成为一个可被3除的数字。 在这个存在的平面上,音乐不能低于0。 例:音量=8:输出=1(键的一击将使你得到6,这是可以被3除的,而不是+键的两次笔划到12)。

我们编写了以下代码:

代码语言:javascript
复制
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整除时,它只通过了基用例测试。

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

代码语言:javascript
复制
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)

作为痕迹:

代码语言:javascript
复制
volume: 2


volume: 4


volume: 6


volume: 2


volume: 4


volume: 6

因此,我们可以编写代码,只需执行递归调用,将值添加到卷中:

代码语言:javascript
复制
function musicalOCD(volume) {
  console.log("\n\nvolume: "+volume);
  if(volume%3==0) return 0;
  return 1+musicalOCD(volume+2);
}

然而,在下列测试中:

代码语言:javascript
复制
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.

如果我们做相反的事情:

代码语言:javascript
复制
function musicalOCD(volume) {
  console.log("\n\nvolume: "+volume);
  if(volume%3==0) return 0;
  return 1+musicalOCD(volume-2);
}

那么22和4的测试将输出2而不是1.

我们如何将这两个递归调用合并到一个一般的答案中?

我们读到:

EN

回答 2

Stack Overflow用户

发布于 2020-03-22 10:24:42

代码语言:javascript
复制
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);
}

票数 1
EN

Stack Overflow用户

发布于 2020-03-22 11:16:53

您可以使用一种方法,通过测试、递减、增强、然后递增来推进递归调用。

代码语言:javascript
复制
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));

有测试指南。

代码语言:javascript
复制
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));
代码语言:javascript
复制
.as-console-wrapper { max-height: 100% !important; top: 0; }

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60798063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档