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


  • 相关阅读:
    生成XML文件。
    使用EHCache需要注意的几个问题
    Spring @Value取值为null或@Autowired注入失败
    Windows安装mosquitto
    Linux学习
    hive 日期格式转换
    正则表达式验证字符串是否为IP
    string字符串根据指定字符进行截取转成对应的集合
    CENTOS7自用简单配置
    git的简单使用
  • 原文地址:https://www.cnblogs.com/youxin/p/3426993.html
Copyright © 2020-2023  润新知