LISP - 列表

  • 简述

    列表一直是传统 LISP 中最重要和最主要的复合数据结构。当今的 Common LISP 提供了其他数据结构,例如向量、哈希表、类或结构。
    列表是单链表。在 LISP 中,列表被构造为一个名为cons联系在一起。
  • cons 记录结构

    Acons是一个包含两个组件的记录结构,称为carcdr.
    Cons cells 或 cons are objects 是使用函数创建的值对cons.
    cons函数接受两个参数并返回一个包含两个值的新 cons 单元格。些值可以是对任何类型对象的引用。
    如果第二个值不是 nil 或另一个 cons 单元格,则些值将打印为用圆括号括起来的点对。
    cons 单元格中的两个值称为carcdr.car函数用于访问第一个值和cdr函数用于访问第二个值。

    例子

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (cons 1 2))
    (terpri)
    (write (cons 'a 'b))
    (terpri)
    (write (cons 1 nil))
    (terpri)
    (write (cons 1 (cons 2 nil)))
    (terpri)
    (write (cons 1 (cons 2 (cons 3 nil))))
    (terpri)
    (write (cons 'a (cons 'b (cons 'c nil))))
    (terpri)
    (write ( car (cons 'a (cons 'b (cons 'c nil)))))
    (terpri)
    (write ( cdr (cons 'a (cons 'b (cons 'c nil)))))
    
    当您执行代码时,它返回以下结果 -
    
    (1 . 2)
    (A . B)
    (1)
    (1 2)
    (1 2 3)
    (A B C)
    A
    (B C)
    
    上面的示例显示了如何使用 cons 结构来创建单个链表,例如,列表 (ABC) 由三个 cons 单元组成,些单元通过它们的cdr链接在一起。
    在图表上,它可以表示为 -
  • LISP 中的列表

    虽然 cons 单元格可用于创建列表,但是,从嵌套中构建列表cons函数调用不是最好的解决方案。list函数更适合用于在 LISP 中创建列表。
    list 函数可以接受任意数量的参数,因为它是一个函数,所以它会计算它的参数。
    firstrest函数给出列表的第一个元素和其余部分。以下示例演示了些概念。

    示例 1

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (list 1 2))
    (terpri)
    (write (list 'a 'b))
    (terpri)
    (write (list 1 nil))
    (terpri)
    (write (list 1 2 3))
    (terpri)
    (write (list 'a 'b 'c))
    (terpri)
    (write (list 3 4 'a (car '(b . c)) (* 4 -2)))
    (terpri)
    (write (list (list 'a 'b) (list 'c 'd 'e)))
    
    当您执行代码时,它返回以下结果 -
    
    (1 2)
    (A B)
    (1 NIL)
    (1 2 3)
    (A B C)
    (3 4 A B -8)
    ((A B) (C D E))
    

    示例 2

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (defun my-library (title author rating availability)
       (list :title title :author author :rating rating :availabilty availability)
    )
    (write (getf (my-library "Hunger Game" "Collins" 9 t) :title))
    
    当您执行代码时,它返回以下结果 -
    
    "Hunger Game"
    
  • 列表操作函数

    下表提供了一些常用的列表操作函数。
    序号 功能说明
    1
    car
    它以一个列表作为参数,并返回它的第一个元素。
    2
    cdr
    它以一个列表作为参数,并返回一个没有第一个元素的列表
    3
    cons
    它有两个参数,一个元素和一个列表,并返回一个列表,其中元素被插入到第一个位置。
    4
    list
    它接受任意数量的参数并返回一个列表,其中参数作为列表的成员元素。
    5
    append
    它将两个或多个列表合并为一个。
    6
    last
    它接受一个列表并返回一个包含最后一个元素的列表。
    7
    member
    它有两个参数,如果第一个参数是第二个参数的成员,那么第二个参数必须是一个列表,然后它返回列表中以第一个参数开头的其余部分。
    8
    reverse
    它接受一个列表并返回一个列表,其中顶部元素的顺序相反。
    请注意,所有序列函数都适用于列表。

    示例 3

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (car '(a b c d e f)))
    (terpri)
    (write (cdr '(a b c d e f)))
    (terpri)
    (write (cons 'a '(b c)))
    (terpri)
    (write (list 'a '(b c) '(e f)))
    (terpri)
    (write (append '(b c) '(e f) '(p q) '() '(g)))
    (terpri)
    (write (last '(a b c d (e f))))
    (terpri)
    (write (reverse '(a b c d (e f))))
    
    当您执行代码时,它返回以下结果 -
    
    A
    (B C D E F)
    (A B C)
    (A (B C) (E F))
    (B C E F P Q G)
    ((E F))
    ((E F) D C B A)
    
  • 汽车和 cdr 功能的串联

    carcdr函数及其组合允许提取列表的任何特定元素/成员。
    但是,可以通过在字母 c 和 r 中连接代表 car 的字母 a 和代表 cdr 的 d 来缩写 car 和 cdr 函数序列。
    例如,我们可以编写 cadadr 来缩写函数调用序列 - car cdr car cdr。
    因此,(cadadr '(a (cd) (efg))) 将返回 d

    例 4

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (cadadr '(a (c d) (e f g))))
    (terpri)
    (write (caar (list (list 'a 'b) 'c)))   
    (terpri)
    (write (cadr (list (list 1 2) (list 3 4))))
    (terpri)
    
    当您执行代码时,它返回以下结果 -
    
    D
    A
    (3 4)