zoukankan      html  css  js  c++  java
  • scheme递归

    主要参考:

    http://www.shido.info/lisp/scheme7_e.html

    Function fact that calculates factorials.

    (define (fact n)
      (if (= n 1)
          1
          (* n (fact (- n 1)))))
    

    (fact 5) is calculated like as follows:

    (fact 5)
    ⇒ 5 * (fact 4)
    ⇒ 5 * 4 * (fact 3)
    ⇒ 5 * 4 * 3 * (fact 2)
    ⇒ 5 * 4 * 3 * 2 * (fact 1)
    ⇒ 5 * 4 * 3 * 2 * 1
    ⇒ 5 * 4 * 3 * 2
    ⇒ 5 * 4 * 6
    ⇒ 5 * 24
    ⇒ 120


    (fact 5) calls (fact 4)(fact 4) calls (fact 3), then finally (fact 1) is called. (fact 5)(fact 4) ,.., and (fact 1) are allocated at different memory spaces and(fact i) stays there until (fact (- i 1)) returns a value, which wastes the memory space and takes more calculation time because of the overhead of function call.

    However, recursive functions can express repetition in a simple manner. Further as lists are defined recursively, lists and recursive functions fit together. For instance, a function that makes all list items twice is defined like as follows. The function should return an empty list if the argument is an empty list to terminate the calculation.

    (define (list*2 ls)
      (if (null? ls)
          '()
          (cons (* 2 (car ls))
    	    (list*2 (cdr ls)))))

    3. Tail Recursive

    Ordinary recursive function is not efficient because of wasting memory and function call overhead. On the contrary, tail recursive functions include the result as argument and returns it directory when the calculation finishes. Especially, as Scheme specification requires conversion of a tail recursive to a loop, there is no function call overhead.

    [code 2] shows a tail recursive version of function fact shown in [code 1].

    [code 2] fact-tail, tail recursive version of fact

    (define (fact-tail n)
      (fact-rec n n))
    
    (define (fact-rec n p)
      (if (= n 1)
          p
          (let ((m (- n 1)))
    	(fact-rec m (* p m)))))
    
    fact-tail calculates factorial like as follows:
    (fact-tail 5)
    ⇒ (fact-rec 5 5)
    ⇒ (fact-rec 4 20)
    ⇒ (fact-rec 3 60)
    ⇒ (fact-rec 2 120)
    ⇒ (fact-rec 1 120)
    ⇒ 120
    
    As fact-rec does not wait the result of other functions, it disappears from the memory space when it finishes. The calculation proceeds by changing argument of fact-rec, which is basically the same as loop. As mentioned previously, as Scheme convert a tail recursive to a loop, Scheme can do repetition without syntax for looping.

    4. Named let

    The named let is available to express loop. [code 3] shows a function fact-let that calculates factorials using named let. The fact-let uses a named let expression (loop), instead of fact-rec shown in [code 2]. First it initializes parameters (n1p) with n at the line marked with ; 1. These parameters are updated at the line marked with ; 2 after each cycle: Subtracting n1 by one and multiplying p by (n1-1)

    A named let is a conventional way to express loops in Scheme.

    [code 3]

    (define (fact-let n)
      (let loop((n1 n) (p n))           ; 1
        (if (= n1 1)                    
    	p
    	(let ((m (- n1 1)))
    	  (loop m (* p m))))))      ; 2

    5. letrec

    While it is similar to the named let, a name defined by letrec can refer itself in its definition. The letrec syntax is used to define complicated recursive functions. [code 4] shows a letrec version of fact.

    [code 4]

    (define (fact-letrec n)
      (letrec ((iter (lambda (n1 p)
    		   (if (= n1 1)
    		       p
    		       (let ((m (- n1 1)))
    			 (iter m (* p m)))))))     ; *
        (iter n n)))
    
    As shown at the line of ; *, the local variable iter can refer itself in the definition of iter. Syntax letrec is a conventional way to define local functions.


  • 相关阅读:
    向量旋转公式推导
    atan函数与atan2函数
    UVALive 7040 Color (容斥原理+逆元+组合数+费马小定理+快速幂)
    关于source insight、添加.s和.S文件,显示全部路径、加入项目后闪屏幕
    linux内核设计与实现--进程调度 系统调用
    linux内核设计与实现--进程管理
    linux命令行与shell脚本编程大全---bash shell命令
    linux内核设计与实现--从内核出发
    Linux内核学习之路
    NAND FLASH均衡算法笔记(转)
  • 原文地址:https://www.cnblogs.com/youxin/p/3426993.html
Copyright © 2011-2022 走看看