当前位置: 首页 > 文档资料 > LISP 中文教程 >

序列(Sequences)

优质
小牛编辑
135浏览
2023-12-01

Sequence是LISP中的抽象数据类型。 向量和列表是此数据类型的两个具体子类型。 序列数据类型上定义的所有功能实际上应用于所有向量和列表类型。

在本节中,我们将讨论序列上最常用的函数。

在开始操作序列的各种方法(即向量和列表)之前,让我们看一下所有可用函数的列表。

创建序列

函数make-sequence允许您创建任何类型的序列。 这个函数的语法是 -

make-sequence sqtype sqsize &key :initial-element

它创建一个sqtype类型和sqsize.长度的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)

序列上的通用函数

Sr.No.功能说明
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

它需要两个序列并返回第一对不匹配元素的索引。

标准序列函数关键字参数

争论含义默认值
:test它是一个双参数函数,用于将项目(或通过:key function提取的值)与元素进行比较。EQL
:key单参数函数从实际序列元素中提取键值。 NIL表示按原样使用元素。NIL
:start开始索引(包括)子序列。0
:end子序列的结束索引(不包括)。 NIL表示序列结束。NIL
:from-end如果为true,则序列将以相反的顺序遍历,从头到尾。NIL
:count数字表示要删除或替换的元素数或NIL表示全部(仅限REMOVE和SUBSTITUTE)。NIL

我们刚刚讨论了在这些函数中用作序列的各种函数和关键字。 在下一节中,我们将看到如何使用示例来使用这些函数。

寻找长度和元素

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

例子 (Example)

创建一个名为main.lisp的新源代码文件,并在其中键入以下代码。

(setq x (vector 'a 'b 'c 'd 'e))
(write (length x))
(terpri)
(write (elt x 3))

执行代码时,它返回以下结果 -

5
D

修改序列

一些序列函数允许迭代序列并执行一些操作,如搜索,删除,计数或过滤特定元素,而无需编写显式循环。

以下示例演示了这一点 -

例子1 (Example 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 (Example 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 (Example 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 (Example 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称为序列谓词​​。

这些函数迭代序列并测试布尔谓词。

所有这些函数都将谓词作为第一个参数,其余参数是序列。

例子 (Example)

创建一个名为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个序列,并在将函数应用于序列的后续元素后返回新序列。

例子 (Example)

创建一个名为main.lisp的新源代码文件,并在其中键入以下代码。

(write (map 'vector #'* #(2 3 4 5) #(3 5 4 8)))

执行代码时,它返回以下结果 -

#(6 15 16 40)