【问题标题】:Loop and recursion: the difference in the number of repetitions循环和递归:重复次数的区别
【发布时间】:2020-04-11 20:36:50
【问题描述】:

这两个函数给出的结果是一样的,但是为什么循环中有“i > 4”而递归中有“size > 5”呢?为什么数字不同?

function branchBoxForLoop(size) {
  c.strokeStyle = "blue";
  for (var i = size; i > 4; i = i * 0.65) {
    c.translate(i, i);
    c.strokeRect(-i, -i, i, i);
  }
}
function branchBox(size) {
  c.translate(size, size);
  c.strokeRect(-size, -size, size, size);
  if (size > 5) {
    branchBox(size * 0.65);
  }
}

【问题讨论】:

    标签: javascript loops recursion


    【解决方案1】:

    它们对All 输入的作用不同,但对于某些输入。

    基本上,这里最大的危险信号是在 recursion 函数中,您甚至在执行 translatestrokeRect 之前都不会检查 size,这意味着它总是至少运行一次。

    匹配的递归函数是这样的(忽略c.strokeStyle = "blue"):

    function branchBox(size) {
      if (size > 4) {
        c.translate(size, size);
        c.strokeRect(-size, -size, size, size);
        branchBox(size * 0.65);
      }
    }
    

    【讨论】:

    • 我相信函数实际上对于大小 7 的行为基本相同。你是对的,在达到 4.55 之后它不会在递归中再次进入函数,但更重要的是它没有不需要再次输入,因为在检查数字是否大于 5 之前调用了相关函数 c.translatec.strokeRect
    • 我已经发布了一个答案,其中列出了 Size 的所有值,这两个函数是不同的。 6、8、9、12、13、14、19 和 20 都在里面,这让我想知道为什么 op 认为它们是相同的......
    • @TKoL 我的错,你是完全正确的,这是漫长的一天.. 很快就会编辑帖子。感谢您的关注
    【解决方案2】:

    我做了一个批量测试两个函数之间匹配和不匹配的方法:

    var c = {
        translate: () => {
            // console.log('translate arguments', arguments)
        },
    
        strokeRect: () => {
            // console.log('strokeRect arguments', arguments)
        }
    }
    
    function* branchBoxForLoop(size) {
      c.strokeStyle = "blue";
      for (var i = size; i > 4; i = i * 0.65) {
        c.translate(i, i);
        c.strokeRect(-i, -i, i, i);
        yield i;
      }
    }
    function* branchBox (size) {
      c.translate(size, size);
      c.strokeRect(-size, -size, size, size);
      yield size;
      if (size > 5) {
        yield* branchBox(size * 0.65);
      }
    }
    
    var matches = [];
    var mismatches = [];
    for (let x = 5; x < 100; x += 0.2) {
      x = x.toFixed(2);
      x = Number(x);
      let a = [...branchBoxForLoop(x)];
      let b = [...branchBox(x)];
      if (JSON.stringify(a) == JSON.stringify(b)) {
        matches.push(x);
      } else {
        mismatches.push(x);
      }
    }
    
    console.log(mismatches);

    [编辑]模式一般是这样的

    这两个函数的行为不同

    (a)每一个大于 5 的值,当你将它乘以 0.65 时,都会产生一个小于 5 的值

    (b) 如果您从 a 中获取所有这些值并将它们乘以 (1/0.65),那么所有这些值的行为也会有所不同

    (c) 如果你从 b 中获取所有这些值并将它们乘以 (1/0.65),那么所有这些值的行为也会有所不同

    以此类推,无限

    【讨论】:

      【解决方案3】:

      实际上,对于输入大小 = 4,它们都会产生不同的结果;代码执行如下。

      // branchBoxForLoop(4)
      c.strokeStyle = "blue";
      
      
      // branchBox(4)
      c.translate(4, 4);
      c.strokeRect(-4, -4, 4, 4);
      

      对于相同的行为,需要进行一致的检查。

      【讨论】:

        猜你喜欢
        • 2019-10-13
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 2014-02-20
        • 2014-12-14
        • 1970-01-01
        • 2011-03-06
        • 2013-03-26
        相关资源
        最近更新 更多