文章目录
blabla ahead
列表是Lisp中最多功能的数据结构。本章将介绍其他数据结构:数组(包含向量和字符串),结构和哈希表。虽然它们不像列表那么灵活,但存取速度更快,并使用更少的空间。
Clisp还有另一种数据结构:实例(instance)。将在11章介绍。
4.1 Array
跟C语言中的类似,但不是使用[]定义或取值,而是使用函数。
make-array 定义数组。> (setf arr (make-array '(2 3) :initial-element nil))
> (make-array 4 :initial-element 4)
Clisp中数组可以达到七个维度,每个维度至少可以容纳1023个元素。 :inital-value 实参是选择性的,提供数组的初值,如果未选择,初值未定义。
aref 取出数组内的元素值,与C语言一致是零索引的。> (aref arr 0 0)
NIL
> (setf (aref arr 0 0) 'b)
B
#na 语法,定义一个常量数组。> #2a((b nil nil) (nil nil nil))
一维数组又称为向量,可以通过调用vector来一步构造即填满向量,向量的元素可以是任意类型。> (setf vec (vector "a" 'b 3))
#("a" 'b 3)
> (svref vec 0)
"A"
svref 来更快速的存取向量,
4.2 Example:Binary Search
4.3 Strings and Charaters
字符串是字符组成的向量,由双引号包括。
字符使用#x表示。
char-code 返回与字符相关的数字
code-char 返回与数字相关的字符
字符比较函数:char=,char>,char/=>(sort "elbow" #'char
"below"
字符串可以使用aref来取值,setf来赋值。针对字符串,可以使用速度更可的char函数来取值。>(char "elbow" 1)
#l
equal 比较字符是否相等
string-equal 忽略大小写,比较字符是否相等。
4.4 Sequences
序列,包含列表和向量(因此也包括字符串)。
有些用在列表的函数,实际上是序列的函数,包括remove,length,subseq,reverse,sort,every,some。
之前介绍个四种取出序列元素的的函数:给列表使用的nth,给向量使用的aref,svref,以及给字符串使用的char。
Clisp也提供通用的elt,对任何序列都有效。
标准关键字参数参数用途缺省值:key应用到每个元素的函数identify
:test用来比较的函数eql
:form-end若为真,反向工作nil
:start起始位置0
:end若有给定,结束位置nil
一些常用的函数
position 返回序列中一个元素的位置,接收上面所有的关键字参数。> (position #a "fantasia")
1
position-if 接收除了:test之外的所有关键字参数。找到满足谓词的第一个元素的位置。> (position-if #'oddp '(2 3 4 5))
1
subseq 提取部分序列
member,memeber-if
find,find-if
remove,remove-if
reduce 用来把序列压缩为一个值。> (reduce #'fn '(a b c d))
类似于> (fn (fn (fn 'a 'b) 'c) 'd)
4.5 Example:Parsing Dates
4.6 Structures
结构体可以看做豪华版的向量。
defstruct 定义结构体。(defstruct point x y)
这里定义了一个point结构,具有两个字段x和y。同时隐式的定义了make-point,point-p,copy-point,point-x,point-y函数。
之前说过,Lisp程序可以写出Lisp程序,这是目前所见的最明显的例子之一。当你调用defstruct时,它自动生成了其他几个函数的定义。有了宏以后,你将可以自己来办到同样的事情(如果有需要的话,你甚至可以自己写出defstruct).
(感觉没什么意思啊,我要的是能在程序运行时候,自己构造程序的程序。而不是开发一门新的编程语言)
每个point类型,首先是point,然后是类型structure,再接着是类型atom,最后是t类型。
4.7 Example:Binary Search Tree
4.8 Hash Tables
make-hash-table 构造hash table
hash table 与关联列表类似,是一种表达对对应关系的方式。
gethash 接收一个键值与hash table,返回两个值,第一个值是与键值相关的数值,第二个值说明表中是否含有与此键值相关的数据。> (setf ht (make-hash-table))
#
> (gethash 'color ht)
NIL
NIL
> (setf (gethash 'color ht) 'color)
RED
> (gethash 'color ht)
RED
T
push 可以用于向hash表添加一个词条> (push 'green (gethash 'color2 ht))
remhash 移除一个对象
maphash 接收两个实参,一个两个参数的函数以及哈希表。该函数会被每个键值对调用。