功能样式链接列表

2013年10月8日

我们将一对表示为带有两个槽的向量。空对表示为零长度向量。头部提取各种元素:

(定义零(矢量));'()

(定义(零?xs)(零?(向量长度xs));无效的?

(定义(对x x x x)(向量x x x s));欺骗

(定义(头部xs);汽车
(如果(零?xs)
(错误'头部“耗尽”)
(矢量参考xs 0))

(定义(尾部xs);信用违约互换
(如果(零?xs)
(错误'tail“耗尽”)
(矢量参考xs 1)

有了这个,我们可以建立一个这样的列表:

>(定义xs(对0(对1(对2(对3(对4(对5(对6(对7无))))
>(头部xs)
0
>(头部(尾部(尾部xs))

第n项是通过倒计时列表中的元素来找到的,直到找到所需的项;列表的长度是通过计算每个元素直到找到最后一个元素来确定的。老式口齿不清者调用检查列表中每个元素的操作cdr-ing向下列表:

(定义(第n个x第n个);列表参考
(如果(零?xs)
(错误'nth“耗尽”)
(如果(零?n)
(头部xs)
(第n个(尾部xs)(-n 1)))

(定义(len xs);长度
(如果(零?xs)
      0
(+(len(tail xs))1))

>(第n个xs 5)
5
>(长度xs)
8

append函数必须向下cdr第一个列表;第二个列表保持不变:

(定义(约x1x2);追加
(如果(零?x1)
2个
(一对(头部x1)
(app(tail x1)x2))

>(第n个(近似xs(第8对(第9对无)))9)
9
>(第n个(近似xs(第8对(第9对无)))10)
错误:nth:已用尽

一个简单的反向调用为列表中的每个项目追加;迭代反转只是在输入累积输出时向下cdr:

(定义(逆xs);颠倒
(如果(零?xs)

(app(逆递归(尾部xs))
(对(头xs)nil)))

(定义(rev-iterative xs);颠倒
(let循环((xs-xs)(rs-nil))
(如果(零?xs)

(回路(尾部xs)(对(头部xs)rs)))

>(第n个(逆行xs)4)

>(第n个(反覆xs)4)

我们就到此为止;《标准序曲》提供了更多列表操作的示例。您可以在上查看上述程序http://programmingpraxis.codepad.org/FPUIwVp0.

页:1 2

3对“功能风格链接列表”的回应

  1. 日本

    直接使用函数表示列表怎么样?功能再好不过了。:)

    ; 空列表(定义为空(λ(l)(l“错误”错误#t)))(定义空?(λ(l)(l(λ; 建立和拆卸列表(定义对(λ(a d)(λ[l)(l a d#f)))(首先定义λ(l)(l(λ(a d e)a))(定义剩余(λ(l)(l(λ

    每个“list”实际上是一个函数,该函数反过来接受三个参数的函数:head、tail和list是否为空。从那里,你可以很快地构建所有东西。更好的是,其余的函数甚至不需要了解实现——它们只需要使用上面给出的四个函数。

    GitHub要点:jpverkamp/6896457
    博客帖子:用作列表

  2. 你所说的“你应该至少包括nil和一个谓词来识别它”是什么意思?

  3. 日本

    nil是空列表。例如,在Scheme中,将是空列表'()谓词应该是无效的?在我上面的例子中,这些是空的空的?.

    这是一个特殊情况,因为它仍然是一个列表,但与所有其他列表不同,它没有头部和尾部,因此返回这些内容的函数工作方式不同。

留下评论