第三章 列表(Lists)
列表是Lisp的基本数据结构之一,在最早的Lisp中,是唯一的数据结构。
cons真正做到事情是将两个对象结合成一个有两部分的对象。
概念上来说,cons是一对指针,第一个是car,第二个是cdr
将cons看成一个箱子,一部分是car,一部分是cdr,这种方式叫做箱子表示法,即和链表一样。
一个列表中的元素又是一个列表,这种属于嵌套列表。一个列表中的元素都不是列表,则成为平坦列表
概念上来说,cons是一对指针,第一个是car,第二个是cdr
将cons看成一个箱子,一部分是car,一部分是cdr,这种方式叫做箱子表示法,即和链表一样。
一个列表中的元素又是一个列表,这种属于嵌套列表。一个列表中的元素都不是列表,则成为平坦列表
上述代码中用箱子表示法表示如下图:
consp:判断一个元素是不是cons对象,是返回真。
eql:比较两个元素是否相等,比较的是完全相等,即是否为相同对象。
equal:比较两个元素的值是否相等,即比较打印的值是否相等。
eql:比较两个元素是否相等,比较的是完全相等,即是否为相同对象。
equal:比较两个元素的值是否相等,即比较打印的值是否相等。
clisp中无法看到显示的指针,不像C那样。
没有指针的原因是每个值在概念上来说都是一个指针。
你可以这么理解:(setf y 2) 此操作是将指向2的指针赋给了y,此时y便指向了2那块内存,当要取内存的值时,lisp返回指向2的指针。
不过也不全是上述的方法,lisp会选择折中的表示法,若一个小整数所需的内存空间少于一个指针所需的空间,则可能会直接处理这个小整数。
copy-list:接收一个列表,并返回此列表的复本。
树
cons对象可以想成二叉树,car代表右子树,cdr代表左子树。
copy-tree:接收一个树,并返回一个副本。
与copy-list的区别:copy-tree复制每一个cons的对象的car与cdr,copy-list只复制cdr。
递归
递归一般要考虑的两个问题:
1、确定一个基本用例,也就是递归到最后跳出递归的那种情况
2、确定在递归时的一些参数的改变。
append:将任何数目的列表拼接。第一个参数要为列表。(append '(1 2) '(3 4) '5)→(1 2 3 4 5)
nth:从列表中取出指定位置元素,第一个参数为位置,第二个参数为列表。从0开始计算
映射函数
mapcar:第一个参数为处理列表元素的函数,接受一个或多个列表。将列表的每个元素应用到函数并返回其处理结果。
例子:(mapcar #'(lambda (x) (+ x 2)) '(1 2 3))→(3 4 5)
maplist:第一个参数为处理列表的函数,接受一个或多个列表。将列表渐进的下一个cdr传入函数。
例子:(maplist #'(lambda (x) x) '(a b c))→((A B C) (B C) (C))
member:第一个参数为要查找的对象,第二个参数为一个列表,返回由寻找到对象所开始的那部分。
nth:从列表中取出指定位置元素,第一个参数为位置,第二个参数为列表。从0开始计算
映射函数
mapcar:第一个参数为处理列表元素的函数,接受一个或多个列表。将列表的每个元素应用到函数并返回其处理结果。
例子:(mapcar #'(lambda (x) (+ x 2)) '(1 2 3))→(3 4 5)
maplist:第一个参数为处理列表的函数,接受一个或多个列表。将列表渐进的下一个cdr传入函数。
例子:(maplist #'(lambda (x) x) '(a b c))→((A B C) (B C) (C))
member:第一个参数为要查找的对象,第二个参数为一个列表,返回由寻找到对象所开始的那部分。
如:(member 'a '(c d a w r q))→(A W R Q)
member接收关键字:test,:test后加一个函数,用于指示查找的条件
member接收关键字:key,:key后加一个函数,在比较之前将函数应用到每一个元素上。
并集(union)、交集(intersection)、补集(complement)
并、交、补集对应的和数学上的概念一样,分别用union、intersection、set-difference函数来实现。
序列
序列包括:列表、向量
序列操作函数
length:返回序列中的元素数
subseq:截取序列元素,对原序列不影响,返回截取从开始位置到结束位置前一个的内容。第一个参数为开始位置,第二个参数为结束位置
reverse:将一个序列倒置。
sort:排序,会破坏原序列。第一个参数为序列,第二个参数为排序函数
every:第一个参数为判断函数,第二个为序列。只有序列中的元素全满足才返回真。
some:第一个参数为判断函数,第二个为序列。只要序列中的一个元素满足,则返回真。
点状列表
正规列表:可以是nil,或cdr部分是正规列表的cons对象。
一个非正规列表的cons对象称为点状列表。
也可以用点状列表表示正规列表。如:'(a .(b .(c .nil))) →(A B C)
关联列表
可以用cons对象来表示映射。
一个由cons对象组成的列表成为关联列表。
assoc:取出在关联列表中,与给定的键值有关联的cons对。
垃圾