`

(译)Scheme简明教程8-递归

阅读更多
 

第六章 递归

 一个过程体中可以包含对其它过程的调用,特别的是也可以调用自己。

(define factorial
 (lambda (n)
    (if (= n 0) 1
        (* n (factorial (- n 1))))))

这个递归过程用来计算一个数的阶乘。如果这个数是0,则结果为1。对于任何其它的值n,这个过程会调用其自身来完成n-1阶乘的计算,然后将这个子结果乘上n并返回最终产生的结果。

互递归过程也是可以的。下面判断奇偶数的过程相互进行了调用。

(define is-even?
 (lambda (n)
    (if (= n 0) #t
        (is-odd? (- n 1)))))
 
(define is-odd?
 (lambda (n)
    (if (= n 0) #f
        (is-even? (- n 1)))))

这里提供的两个过程的定义仅作为简单的互递归示例。Scheme已经提供了简单的判断过程even? odd?

6.1          letrec

如果希望将上面的过程定义为局部的,我们会尝试使用let结构:

(let ((local-even? (lambda (n)
                     (if (= n 0) #t
                         (local-odd? (- n 1)))))
      (local-odd? (lambda (n)
                    (if (= n 0) #f
                        (local-even? (- n 1))))))
 (list (local-even? 23) (local-odd? 23)))

但这并不能成功,因为在初始化值过程中出现的local-even? local-odd?指向的并不是这两个过程本身。把let换成let*同样也不能奏效,因为这时虽然local-odd?中出现的local-even?指向的是前面刚创建好的局部的过程,但local-even? 中的local-odd?还是指向了别处。

为解决这个问题,Scheme提供了letrec结构。

(letrec ((local-even? (lambda (n)
                        (if (= n 0) #t
                            (local-odd? (- n 1)))))
         (local-odd? (lambda (n)
                       (if (= n 0) #f
                           (local-even? (- n 1))))))
 (list (local-even? 23) (local-odd? 23)))

letrec创建的词法变量不仅可以在letrec执行体中可见而且在初始化中也可见。letrec是专门为局部的递归和互递归过程而设置的。(这里也可以使用define来创建两个子结构的方式来实现局部递归)

6.2          已命名let

使用letrec定义递归过程可以实现循环。如果我们想显示101的降数列,可以这样写:

(letrec ((countdown (lambda (i)
                      (if (= i 0) 'liftoff
                          (begin
                            (display i)
                            (newline)
                            (countdown (- i 1)))))))
 (countdown 10))

这会在控制台上输出101,并会返回结果liftoff

Scheme允许使用一种叫已命名letlet变体来更简洁的写出这样的循环:

(let countdown ((i 10))
 (if (= i 0) 'liftoff
      (begin
        (display i)
        (newline)
        (countdown (- i 1)))))

注意在let的后面立即声明了一个变量用来表示这个循环。这个程序和先前用letrec写的程序是等价的。你可以将已命名let看成一个对letrec结构进行扩展的宏。

分享到:
评论

相关推荐

    Fluent_Scheme简明中文手册-带书签.pdf

    5. Fluent-Scheme-UDFs的高级特性,例如如何使用RP_Get和RP_Set函数在运行时获取和设置变量的值。 6. Fluent-Scheme的内置函数库,可能包括用于数学计算的函数、字符串处理函数等。 7. 与Fluent图形用户界面(GUI)...

    scheme简明教程

    这是一本在国外比较有名的Scheme编程语言的入门教材。本教材适合任何对Scheme编程语言感兴趣的人阅读,尤其是有其他编程语言(特别是动态语言)编程经验,希望快速了解Scheme的不同点并且快速上手写点东西的人。

    A unified scheme for adaptive stroke-based rendering.pdf

    标题与描述中的“统一方案(unified scheme)”与“基于笔触的自适应渲染(adaptive stroke-based rendering)”是本文的关键概念,涉及到计算机图形学领域中的非摄影真实感渲染技术(NPR)。该论文由Hyung W. Kang...

    fluent——scheme简明中文手册

    由于提供的文件内容片段实际上并没有提供关于标题“fluent——scheme简明中文手册”的具体内容,而是呈现了一些无序的数字和章节标题,我们无法直接基于这些片段生成详尽的知识点。但我们可以根据手册的标题,以及...

    CorSegRec: A Topology-Preserving Scheme for Extracting Fully-Con

    CorSegRec: A Topology-Preserving Scheme for Extracting Fully-Connected Coronary Arteries from CT Angiography CorSegRec:拓扑保持 全连通提取方案 冠状动脉CT血管造影

    Android-scheme-libscheme-lib是一个scheme使用的库

    **Android Scheme Libs: Scheme-Lib for Android** Scheme-Lib是一个专门为Scheme编程语言设计的库,特别针对Android平台进行了优化和适配。Scheme是一种历史悠久、功能强大的Lisp方言,以其简洁的语法和强大的函数...

    A Preprocessing Scheme for High-Cardinality Categorical Attributes

    "A Preprocessing Scheme for High-Cardinality Categorical Attributes"这个主题探讨的就是如何有效地处理这类问题。 一、高基数类别变量的挑战 1. 维度灾难:高基数会导致数据的维度增加,这可能会引起过拟合,...

    A novel color image watermarking scheme in nonsampled contourlet-domain

    ### 一种非采样轮廓域中的新型彩色图像水印方案 #### 概述 本文介绍了一种基于非采样轮廓变换(NSCT)和支持向量回归(SVR)技术的新型彩色图像水印算法。该算法针对几何畸变攻击具有良好的抵抗能力,能够在保持...

    fluent_scheme语言手册

    3. **Arithmetische Funktionen, globale und lokale Scheme-Variablen**: - 算术函数部分介绍了在Scheme中进行数学计算的函数,如加、减、乘、除等。 - 全局变量和局部变量部分解释了Scheme语言中变量的作用域和...

    scheme语言中文教程

    和Gerald Jay Sussman发明,其特点包括静态作用域和严格的尾递归优化,它旨在拥有清晰和简明的语义,并且在风格上支持命令式、函数式和消息传递式编程。 在Scheme语言的中文教程中,初学者可以通过详细学习其语法和...

    In-pixel charge addition scheme applied in time-delay integration CMOS image sensors

    An addition scheme applicable to time-delay integration (TDI) CMOS image sensor is proposed, which adds signals in the charge domain in the pixel array. A two-shared pixel structure adopting two-...

    Mit.Press-Teach.Yourself.Scheme.pdf (英文)

    《Teach Yourself Scheme in Fixnum Days》是一本详尽的教程,旨在帮助读者在有限的时间内掌握Scheme语言的基础及进阶知识。此书由Dorai Sitaram撰写,并且在网络上部分中文翻译已经存在(参考链接:...

    Python库 | scheme-2.0.2.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:scheme-2.0.2.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    HA-ColorSchemeDesigner09-yfy

    《HA-ColorSchemeDesigner09-yfy:探索配色艺术与专业工具的奥秘》 在数字设计领域,色彩搭配是至关重要的一环,它能够直接影响到用户对产品的第一印象和使用体验。"HA-ColorSchemeDesigner09-yfy" 是一款专为设计...

    mit-scheme-fererence

    - **标题**:“mit-scheme-fererence”(应当是“MIT Scheme Reference”的误拼)指向了MIT Scheme的一个版本的手册,这是一份详尽的技术文档,用于指导用户如何有效地使用MIT Scheme这一Lisp方言进行编程。...

    PyPI 官网下载 | calysto_scheme-1.4.5-py2.py3-none-any.whl

    标题中的"PyPI 官网下载 | calysto_scheme-1.4.5-py2.py3-none-any.whl"表明这是一个从Python Package Index (PyPI)官方源下载的软件包,具体是`calysto_scheme`的1.4.5版本。PyPI是Python社区最常用的第三方库分发...

    mit-scheme的基本使用教程

    《MIT-Scheme的基本使用教程》 MIT-Scheme是一款基于R5RS标准的Scheme实现,它以其简洁、高效和可扩展性著称。本教程将详细讲解如何使用MIT-Scheme进行编程,包括在命令行环境和Emacs编辑器下的操作。 一、MIT-...

    scheme-to-js:使用scheme编写的scheme-> js编译器

    方案到js 方案->用方案编写...例$ cat example.scm(load "compiler.scm")(display (scheme->js (begin (define (string-join strs joiner) (define (helper strs acc) (if (null? strs) acc (helper (cdr strs) (+ acc

    scheme 语言 实现递归

    Dr.Racket, r5s5 语言写的一个简单递归, 可以计算阶乘。

Global site tag (gtag.js) - Google Analytics