【问题标题】:How can I write this algorithm using iteration?如何使用迭代编写此算法?
【发布时间】:2018-08-30 22:10:15
【问题描述】:

如何使用迭代编写此算法?

function generate(num1:byval) 
     if num1 > 10 then 
          return 10 
     else 
          return num1 + (generate(num1 + 1) DIV 2) 
     endif 
endfunction

【问题讨论】:

    标签: recursion iteration


    【解决方案1】:

    所以这不是直截了当的,所以我先做一些繁重的工作:

    n    result
    11.. 10
    10   10
    9    9 + 10/2
    8    8 + (9 + 10/2)/2
    7    7 + (8 + (9 + 10/2)/2)/2
    

    这看起来像一种模式。虽然递归版本从输入开始并向上移动,但很容易看出,从 10 开始向下移动,可以通过将值减半并添加当前值来简单地更新累加器。

    这可以使用助手轻松实现:

    procedure generate(num : integer) : integer
    begin
      generate := generateHelper(10, num, 0)
    end
    
    
    procedure generateHelper(cur : integer, num: integer, acc : integer) : integer
    begin
      if cur = num then     
        generateHelper := cur + acc/2;
      else
        generateHelper := generateHelper(cur - 1, num, acc/2 + cur);
    end
    

    或者使用循环:

    procedure generate(num : integer) : integer
    var cur, acc : integer;
    begin
      for cur := 10 downto cur do
          acc := acc / 2 + cur;
      generate := acc;
    end
    

    【讨论】:

    • function generate(n) { return n > 10 ? 10 : n > 7 ? (17 - n) * n / 2 - 20 : n * 2 + 1 + (n > -2 ? 0 : 1); }
    • @melpomene 不错。事实上,它是如此有规律,以至于人们可能会在 O(1) 中找到任何 n 之和的公式。那不符合迭代的条件,对吗?
    【解决方案2】:

    如果你为函数计算出一些值……

    f(10) = 10
    f(9) = 9+f(10)/2 = 9+10/2 = 14
    f(8) = 8+f(9)/2 = 8+14/2 = 15
    …
    

    您会感觉到,您可以重复地将相同的公式应用于循环中的值。你看看如果你从 10 开始,你除以 2 加 9,然后除以 2 加 8,然后继续下去,直到你达到给函数的数字。那看起来像这样,例如在 JavaScript 中:

    function generate(n) {
      let x = 10;
    
      for(let i = 10; i > n; i--) {
        x = i - 1 + x / 2;
      }
    
      return x;
    }
    

    【讨论】:

    • if(n >= 10) return 10; 是多余的。
    • @melpomene 谢谢,我在发布之前正在编辑,却忘了把它拿出来。
    猜你喜欢
    • 1970-01-01
    • 2020-08-24
    • 2014-06-04
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    相关资源
    最近更新 更多