码迷,mamicode.com
首页 > 其他好文 > 详细

Common Lisp学习笔记(六)

时间:2015-05-04 23:31:00      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

6 list data structure

首先注意cons的用法
(cons ‘w ‘(x y z)) -> (w x y z)
但是想在list的结尾添加一个元素就不能这样实现,eg,
(cons ‘(w x y) ‘z) -> ((w x y) . z)

6.3 the APPEND function

append函数可以参数是两个list,并将两个list的元素合并在一起,如果其中有一个是nil,则结果和另一个list相同

> (append ‘(a b) ‘(c d))
(a b c d)
> (append ‘(a b) nil)
(a b)
> (append nil ‘(a b))
(a b)
> (append nil nil)
nil
> (append ‘((a 1) (b 2)) ‘((c 3) (d 4)))
((a 1) (b 2) (c 3) (d 4)

append函数不会改变变量的值,是nondestructive的,eg,

> (setf who ‘(only the good))
(only the good)
> (append who ‘(die young))
(only the good die yound)
> who
(only the good)

append函数执行时,会将第一个list复制一份,然后将最后一个元素的cdr指向第二个list,因此如果参数中第一个不是list的话会出错,而如果第二个不是list则可以执行


cons, list, append都能用来构建list,注意区分它们的用法

6.5 more functions on lists

已经学习过的有cons,list,append,length,现在增加新的reverse,nth,nthcdr,lase,remove

  • reverse: 返回一个list的倒序,只对list的第一级元素操作,对list中的list不会改变顺序,也是nondestructive
  • nthcdr: 返回第n个元素的cdr,如果n为0则返回list本身,如果n大于长度则返回nil,eg,

(nthcdr 1 ‘(a b c)) -> (b c)

  • nth: 定义如下
    (defun nth (n x) (car (nthcdr n x)))
    

(nth 0 ‘(a b c)) -> a

  • last: 返回最后一个cons, eg, (last ‘(a b c . d)) -> (c . d)
  • remove: 将某个元素从list中删除,如果不是特别指明则删除这个元素的所有出现,remove是nondestructive的
    (remove ‘a ‘(b a n a n a) -> ( b n n)
    
6.6 list as sets

集合是无序的,每个元素只出现一次,操作有union,intersection,set difference...

member:如果这个元素在list中能够找到则返回以这个item开头的一个子list,如果找不到则返回nil

> (setf ducks ‘(a b c))
(a b c)
> (member ‘b ducks)
(b c)
> (member ‘d ducks)
nil
  • intersection: 返回两个list的交集,顺序是无法保证即随机出现的,当一个list中某个元素不止一个的时候,也可以返回交集,但是该元素是否出现多个是未定义的
  • union
  • set-difference: 返回的差集顺序也是随机的
  • subsetp: 一个list是否是另一个的子集,返回t或者nil

ex 6.26

(defun right-side (x) 
  (rest (member ‘-vs- x)))

(defun left-side (x)
  (reverse (rest(member ‘-vs- (reverse x)))))

(defun count-common (x y) 
  (length (intersection x y)))

(defun compare (x) 
  (count-common (left-side x) (right-side x)))
6.8 list as tables

table: association list ,是list的list,其中的每一个元素都是一个list,它们的car是它们的key,eg,

(setf words
    ‘((one un)
      (two deux)
      (three trois)))

assoc函数在一个table中通过每一个list的第一个元素即car来作为关键字查找,返回这个list,eg,
(assoc ‘three words) -> (three trois)
(assoc ‘six words) -> nil

rassoc: reverse assoc, 通过每个list的cdr来进行查找,返回这个list,eg,

(setf sounds
    ‘((cow . moo)
      (pig . oink)
      (cat . meow)))

(rassoc ‘moo sounds) -> (cow . moo)
6.9 program with tables

创建一个全局变量table things

(setf things ‘((object1 large green shiny cube)
               (object2 small red dull metal cube)
               (object3 red small dull plastic cube)
               (object4 small dull blue metal cube)
               (object5 small shiny red four-sided pyramid)
               (object6 large shiny green sphere)))

里面每个list的第一个item是对象名字,剩下的是描述

定义函数返回对象的描述:

(defun description (x)
  (rest ‘(assoc x things)))

> (description ‘object3) -> (red small ... )

给出两个对象,要找出他们属性中不同的item的集合,定义函数:

(defun differences (x y)
  (set-exclusive-or (description x)
                    (description y)))

> (differences ‘object2 ‘object3) -> (metal plastic)

假如有这样一个表格,可以把某项属性的具体描述映射到属性名字,eg,

(setf quality-table
  ‘((large . size)
    (small . size)
    (red . color)
    (green . color)
    ...)
)

这种表格可以通过assoc来获取属性名字,定义函数来获取属性名字:

(defun quality (x)
  (cdr (assoc x quality-table)))

> (quality ‘red) -> color

现在希望给出两个对象,返回它们不同的属性名字的集合,函数如下:

(defun contrast (x y)
  (remove-duplicates
    (sublis quality-table (differences x y))))

> (contrast ‘object3 ‘object4) -> (color material)

remove-duplicates是集合函数中消除重复出现的,sublis将(differences x y)中返回的具体描述的集合映射到属性名字中

ex 6.29

(length table-name)

ex 6.30

(setf books 
  ‘((war-and-peace  leo-tolstoy)
    (for-whom-the-bell-tolls  haimingwei)
    (lao-ren-yu-hai  haimingwei)
    (meng-de-jie-xi  fuluoyide)
    (lang-chao-zhi-dian  wujun)))

ex 6.31

(defun who-wrote (x)
  (first (cdr (assoc x books))))

> (who-wrote lang-chao-zhi-dian) -> wujun

ex 6.32

who-wrote函数还是返回相同的东西,因为reverse只是把table中所有list的顺序改变,没有改变每个list中内容的顺序

ex 6.33

用assco不能通过作者名字得到书名,除非作者和书名的顺序相反


总结:在lisp中,list可以用来实现其他的数据结构如settable

ex 6.36

(defun cut-first-last (x)
    (reverse (rest (reverse (rest x)))))

(defun swap-first-last (x)
    (append (append (last x) (cut-first-last x)) (cons (first x) nil)))

注意last返回的是最后一个cons,所以可以直接用append进行拼接而不是用cons再加一层list

ex 6.37

(defun rotate-left (x)
    (append (rest x) (cons (first x) nil)))

Common Lisp学习笔记(六)

标签:

原文地址:http://www.cnblogs.com/jolin123/p/4477694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!