• 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.


  • 相关阅读:
    C# EPPlus 导出Excel
    NetCore +EF+Mysql 从数据库生成实体类到项目
    VBA链接SQL server数据库
    sqlserver中的 binary varbinary image
    sql server DateTime与DateTime2的区别
    Sql Server增删改查字段的语法
    c#中queue的用法
    Sql Server中不相关的两个数据表的全部显示
    IActionResult的返回值类型
    linux内存映射
  • 原文地址:https://www.cnblogs.com/youxin/p/3426993.html
Copyright © 2020-2023  润新知