LISP - 队列

  • 简述

    队列是 LISP 中的一种抽象数据类型。向量和列表是该数据类型的两个具体子类型。在队列数据类型上定义的所有功能实际上都应用于所有向量和列表类型。
    在本节中,我们将讨论队列上最常用的函数。
    在开始各种操作队列(即向量和列表)的方法之前,让我们看一下所有可用函数的列表。
  • 创建队列

    函数 make-sequence 允许您创建任何类型的队列。个函数的语法是 -
    
    make-sequence sqtype sqsize &key :initial-element
    
    它创建一个类型为sqtype且长度为sqsize的队列
    您可以选择使用:initial-element参数指定一些值,然后每个元素都将初始化为该值。
    例如,创建一个名为 main.lisp 的新源代码文件并在其中键入以下代码。
    
    (write (make-sequence '(vector float) 
       10 
       :initial-element 1.0))
    
    当您执行代码时,它返回以下结果 -
    
    #(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)
    
  • 队列上的泛型函数

    序号 功能说明
    1
    elt
    它允许通过整数索引访问单个元素。
    2
    length
    它返回队列的长度。
    3
    subseq
    它通过提取从特定索引开始并继续到特定结束索引或队列末尾的子队列来返回子队列。
    4
    copy-seq
    它返回一个包含与其参数相同元素的队列。
    5
    fill
    它用于将队列的多个元素设置为单个值。
    6
    replace
    它采用两个队列,并且通过将第二个参数队列中的连续元素复制到其中来破坏性地修改第一个参数队列。
    7
    count
    它接受一个项目和一个队列,并返回该项目在队列中出现的次数。
    8
    reverse
    它返回一个包含参数相同元素但顺序相反的队列。
    9
    nreverse
    它返回包含与队列相同但顺序相反的元素的相同队列。
    10
    concatenate
    它创建一个包含任意数量队列串联的新队列。
    11
    position
    它接受一个项目和一个队列,并返回队列中项目的索引或 nil。
    12
    find
    它需要一个项目和一个队列。它在队列中找到项目并返回它,如果没有找到则返回 nil。
    13
    sort
    它接受一个队列和一个双参数谓词,并返回队列的排序版本。
    14
    merge
    它需要两个队列和一个谓词,并根据谓词返回通过合并两个队列产生的队列。
    15
    map
    它接受一个 n 参数函数和 n 个队列,并返回一个新队列,其中包含将函数应用于队列的后续元素的结果。
    16
    some
    它以谓词作为参数并遍历参数队列,并返回谓词返回的第一个非 NIL 值,如果永远不满足谓词则返回 false。
    17
    every
    它采用谓词作为参数并遍历参数队列,一旦谓词失败,它就会终止并返回 false。如果谓词始终满足,则返回 true。
    18
    notany
    它以谓词作为参数并遍历参数队列,并在谓词满足时立即返回 false,否则返回 true。
    19
    notevery
    它以谓词作为参数并遍历参数队列,并在谓词失败时立即返回 true,如果始终满足谓词则返回 false。
    20
    reduce
    它映射单个队列,首先将双参数函数应用于队列的前两个元素,然后应用于函数返回的值和队列的后续元素。
    21
    search
    它搜索队列以定位一个或多个满足某些测试的元素。
    22
    remove
    它接受一个项目和一个队列,并返回删除项目实例的队列。
    23
    delete
    也需要一个项目和一个队列,并返回一个与参数队列相同种类的队列,该队列具有除项目之外的相同元素。
    24
    substitute
    它接受一个新项、一个现有项和一个队列,并返回一个队列,其中现有项的实例替换为新项。
    25
    nsubstitute
    它接受一个新项目、一个现有项目和一个队列,并返回相同的队列,其中现有项目的实例替换为新项目。
    26
    mismatch
    它接受两个队列并返回第一对不匹配元素的索引。
  • 标准队列函数关键字参数

    Argument Meaning 默认值
    :test 它是一个双参数函数,用于将项目(或由 :key 函数提取的值)与元素进行比较。 EQL
    :key 从实际队列元素中提取键值的单参数函数。NIL 表示按原样使用元素。 NIL
    :start 子队列的起始索引(包括)。 0
    :end 子队列的结束索引(不包括)。NIL 表示队列结束。 NIL
    :from-end 如果为真,则队列将以相反的顺序从头到尾遍历。 NIL
    :count 表示要删除或替换的元素数的数字或 NIL 表示全部(仅删除和替换)。 NIL
    我们刚刚讨论了在处理队列的些函数中用作参数的各种函数和关键字。在接下来的部分中,我们将通过示例了解如何使用些功能。
  • 求长度和元素

    length函数返回队列的长度,并且elt函数允许您使用整数索引访问单个元素。

    例子

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (setq x (vector 'a 'b 'c 'd 'e))
    (write (length x))
    (terpri)
    (write (elt x 3))
    
    当您执行代码时,它返回以下结果 -
    
    5
    D
    
  • 修改队列

    一些队列函数允许迭代队列并执行一些操作,如搜索、删除、计数或过滤特定元素,而无需编写显式循环。
    以下示例演示了一点 -

    示例 1

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (count 7 '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (remove 5 '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (delete 5 '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (substitute 10 7 '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (find 7 '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (position 5 '(1 5 6 7 8 9 2 7 3 4 5)))
    
    当您执行代码时,它返回以下结果 -
    
    2
    (1 6 7 8 9 2 7 3 4)
    (1 6 7 8 9 2 7 3 4)
    (1 5 6 10 8 9 2 10 3 4 5)
    7
    1
    

    示例 2

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (delete-if #'oddp '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (delete-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5)))
    (terpri)
    (write (remove-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5) :count 1 :from-end t))
    (terpri)
    (setq x (vector 'a 'b 'c 'd 'e 'f 'g))
    (fill x 'p :start 1 :end 4)
    (write x)
    
    当您执行代码时,它返回以下结果 -
    
    (6 8 2 4)
    (1 5 7 9 7 3 5)
    (1 5 6 7 8 9 2 7 3 5)
    #(A P P P E F G)
    
  • 排序和合并队列

    排序函数采用一个队列和一个双参数谓词,并返回队列的排序版本。

    示例 1

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'<))
    (terpri)
    (write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'>))
    (terpri)
    
    当您执行代码时,它返回以下结果 -
    
    (1 2 3 3 4 4 5 6 7 8 9)
    (9 8 7 6 5 4 4 3 3 2 1)
    

    示例 2

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (merge 'vector #(1 3 5) #(2 4 6) #'<))
    (terpri)
    (write (merge 'list #(1 3 5) #(2 4 6) #'<))
    (terpri)
    
    当您执行代码时,它返回以下结果 -
    
    #(1 2 3 4 5 6)
    (1 2 3 4 5 6)
    
  • 队列谓词

    函数 every、some、notany 和 notevery 称为队列谓词​​。
    些函数遍历队列并测试布尔谓词。
    所有些函数都将谓词作为第一个参数,其余参数是队列。

    例子

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (every #'evenp #(2 4 6 8 10)))
    (terpri)
    (write (some #'evenp #(2 4 6 8 10 13 14)))
    (terpri)
    (write (every #'evenp #(2 4 6 8 10 13 14)))
    (terpri)
    (write (notany #'evenp #(2 4 6 8 10)))
    (terpri)
    (write (notevery #'evenp #(2 4 6 8 10 13 14)))
    (terpri)
    
    当您执行代码时,它返回以下结果 -
    
    T
    T
    NIL
    NIL
    T
    
  • 映射队列

    我们已经讨论了映射函数。同样的map函数允许您将函数应用于一个或多个队列的后续元素。
    map函数接受一个 n 参数函数和 n 个队列,并在将函数应用于队列的后续元素后返回一个新队列。

    例子

    创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
    
    (write (map 'vector #'* #(2 3 4 5) #(3 5 4 8)))
    
    当您执行代码时,它返回以下结果 -
    
    #(6 15 16 40)