ANSI Common Lisp譯本筆記2

第三章  列表(Lists)


列表是Lisp的基本數據結構之一,在最早的Lisp中,是唯一的數據結構。

cons真正做到事情是將兩個對象結合成一個有兩部分的對象。
概念上來說,cons是一對指針,第一個是car,第二個是cdr
將cons看成一個箱子,一部分是car,一部分是cdr,這種方式叫做箱子表示法,即和鏈表一樣。
一個列表中的元素又是一個列表,這種屬於嵌套列表。一個列表中的元素都不是列表,則成爲平坦列表

上述代碼中用箱子表示法表示如下圖:
 

consp:判斷一個元素是不是cons對象,是返回真。


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:第一個參數爲要查找的對象,第二個參數爲一個列表,返回由尋找到對象所開始的那部分。
 如:(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對。
 

垃圾


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章