零零乙 2010-03-02 19:18 采纳率: 33.3%
浏览 212
已采纳

不知道如何解决 SICP 练习1.11

Exercise 1.11:

A function f is defined by the rule that f(n) = n if n < 3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n > 3. Write a procedure that computes f by means of a recursive process. Write a procedure that computes f by means of an iterative process.

Implementing it recursively is simple enough. But I couldn't figure out how to do it iteratively. I tried comparing with the Fibonacci example given, but I didn't know how to use it as an analogy. So I gave up (shame on me) and Googled for an explanation, and I found this:

(define (f n)
   (if (< n 3)
       n
       (f-iter 2 1 0 n)))

(define (f-iter a b c count)
   (if (< count 3)
       a
       (f-iter (+ a (* 2 b) (* 3 c))
               a
               b
               (- count 1))))

After reading it, I understand the code and how it works. But what I don't understand is the process needed to get from the recursive definition of the function to this. I don't get how the code could have formed in someone's head.

Could you explain the thought process needed to arrive at the solution?

转载于:https://stackoverflow.com/questions/2365993/no-idea-how-to-solve-sicp-exercise-1-11

  • 写回答

5条回答 默认 最新

  • hurriedly% 2010-03-02 19:45
    关注

    You need to capture the state in some accumulators and update the state at each iteration.

    If you have experience in an imperative language, imagine writing a while loop and tracking information in variables during each iteration of the loop. What variables would you need? How would you update them? That's exactly what you have to do to make an iterative (tail-recursive) set of calls in Scheme.

    In other words, it might help to start thinking of this as a while loop instead of a recursive definition. Eventually you'll be fluent enough with recursive -> iterative transformations that you won't need to extra help to get started.


    For this particular example, you have to look closely at the three function calls, because it's not immediately clear how to represent them. However, here's the likely thought process: (in Python pseudo-code to emphasise the imperativeness)

    Each recursive step keeps track of three things:

    f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) 
    

    So I need three pieces of state to track the current, the last and the penultimate values of f. (that is, f(n-1), f(n-2) and f(n-3).) Call them a, b, c. I have to update these pieces inside each loop:

    for _ in 2..n:
        a = NEWVALUE
        b = a
        c = b
    return a
    

    So what's NEWVALUE? Well, now that we have representations of f(n-1), f(n-2) and f(n-3), it's just the recursive equation:

    for _ in 2..n:
        a = a + 2 * b + 3 * c
        b = a
        c = b
    return a
    

    Now all that's left is to figure out the initial values of a, b and c. But that's easy, since we know that f(n) = n if n < 3.

    if n < 3: return n
    a = 2 # f(n-1) where n = 3
    b = 1 # f(n-2)
    c = 0 # f(n-3)
    # now start off counting at 3
    for _ in 3..n:
        a = a + 2 * b + 3 * c
        b = a
        c = b
    return a
    

    That's still a little different from the Scheme iterative version, but I hope you can see the thought process now.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分