数组
创建
(make-array 3); (NIL NIL NIL)
(make-array '(2 3)); ((NIL NIL NIL) (NIL NIL NIL))
一维数组直接传入数值,多位数组传入列表
初始
(make-array '(2 3) :initial-element 1); ((1 1 1) (1 1 1))
(make-array '(2 3) :initial-element (1)); (((1) (1) (1)) ((1) (1) (1)))
可以指定初始化值,默认为NIL
,可以指定为任意指。
访问
(setf arr (make-array 3 :initial-element 1));
(aref arr 1); 1
(setf arr (make-array '(2 3) :initial-element 2))
(aref arr 1 1); 1
和其他的语言不一样,不存在数组嵌套数组构成多维数组的情况。
也就是说,(aref arr 0)
,当arr
为多维数组的时候,是失败而不是返回一个数组。
设置
(setf arr (make-array 3)); (NIL NIL NIL)
(setf (aref arr 1) 9); (NIL 9 NIL)
(aref arr 1); 9
lisp
的非基本数值,都是指针,所以(aref arr 1)
可以取值,同样可以进行赋值,主要依赖指针进行操作。
向量
一维数组,可以当作向量,使用特殊的方法操作更快。
- 创建
(setf arr (vector 'a 'b 'c)); (A B C)
可以把vector
同list
进行对比,很快就能理解。
- 查看
(aref arr 1); A
(svref arr 1); A
使用aref
也能查看,但是针对的svref
查询更快。
二分查找
(defun binary-search (arr start end target) (
let ((len (length arr)))
; 如果长度为0
; 或者全部不匹配
(if (or (zerop len) (eql start end))
; 返回NIL
nil
; 如果等于开头
(if (eql target (svref arr start))
; 返回开始索引
start
; 如果等于结尾
(if (eql target (svref arr end))
; 返回末尾索引
end
; 计算中心值
(let ((mid (/ (+ start end) 2)))
; 取得中心值
(let ((value (svref arr mid)))
; 如果大于
(if (> target mid)
; (mid, end)
(binary-search arr mid end target)
; (start, end)
(binary-search arr start mid target)
)
; 中心变端点,就不重复比对了,想缩减压栈,可再比对一遍
)
)
)
)
)
)
)
(setf arr (vector 1 2 3 4 5 6 7 8 9))
(binary-search arr 0 8 5); 4
(svref arr 4); 5
字符串
声明
(setf str "mlpokijnbhuygvcftrdxzseawq")
注意:是双引号
查看
(aref str 0); m
(char str 2); p
像一维数组那样访问也行,推荐char
修改
(setf (aref str 0) #\M); "M...."
(setf (char str 0) #'m); m...
配合访问指针进行操作
#/
标示字符
排序
(sort str #'char<); (a...z)
改动的依然是本体数据,需要注意
连接
(concatenate 'string "head" " body " "tail"); "head body tail"
连接多个字符串
'string, 特殊名称
比较
(equal "abc" "abc"); T
(equal "abc" "ABC"); NIL
(string-equal "abc" "ABC"); T
- 直接比较:
equal
- 忽略大小写:
steing-equal
序列
- 列表
- 向量
- 字符串
以上都是序列,如下函数都普遍使用于序列
function description remove 移除 length 长度 subseq 截取 reverse 反转 sort 排序 every 全部 some 一些
查看
(elt '(a b c) 1); B
elt
是序列通用的查看方法:
- 数组:
aref
,svref
- 列表:
nth
具体参数如下
param | description |
---|---|
:key | 元素变化 |
:from-end | 反向查找 |
:test | 条件检测 |
:start | 起始位置 |
:end | 结束位置 |
如果想通过元素查找,而非索引的话
(position #\b "abc"); 1
(position-if #'(lambda (x) (equal x #\b)) "abc")
类似的还有这几种,但是参数不一定都支持
member
member-if
find
find-if
reduce
(reduce #'+ '(1 2 3 4 5 6 7 8 9))
作用不多说,打架都知道
去重
(remove-duplicates '( 1 2 1 1 1 4 4 2 3));(1 4 2 3)
只保留最后一个值,所以去重来
输出
(setf result (format nil "~A" 'fuck))
原来的format
中传入的是t
,当传入nil
,不会打印,但是会把打印值直接返回
结构
定义
(defstruct person name age gender)
第一个参数为结构体名称,后续都是该结构的属性字段
方法
定义结构之后,会自动生成各种方法
- 构造
(make-person); #S(PERSON :NAME NIL :AGE NIL :GENDER NIL)
属性默认都是
NIL
,但是可以自己传入指定的值(make-person :name 'godme :age 99 :gender 'male) ; #S(PERSON :NAME GODME :AGE 99 :GENDER MALE)
没有设置的保留默认
NIL
- 属性指针
(person-name p); svref的访问,查询和设置两用
- 类型校验
(person-p p); 类型检查
查询
(setf p (make-person :name 'godme :age 99 :gender 'male))
(person-name p); GODME
设置
(setf (person-name p) 'judas);
(person-name p); JUDAS
类型
(person-p p); T
(type-p p 'person); T
hash
创建
(make-hash-table);
(make-hash-table :size 5); 可指定初始化长度
(setf colors (make-hash-table));
查询
(gethash 'r colors); NIL;NIL
- 第一个:存储的值,找不到时候返回
NIL
- 第二个:是否存储,当
T
表示存储的时候,NIL
才是存储的值,否则仅仅是默认返回的NIL
设置
(setf (gethash 'r colors) 'red);
(gethash 'r colors); RED; T
(setf (gethash 'b colors) '(black dark))
(gethash 'b colors); (BLACK DARK)
- 还是查询索引指针进行赋值
- 支持各种元素
移除
(remhash 'b colors); (R.RED)
比较
(setf (gethash '(1 2 3) colors) '(4 5 6));键值还可以是对象
(gethash '(1 2 3) colors); NIL; NIL; 但是取出来就有问题
因为默认的比较方法是eql
,也就是说,只有是同一个对象,是同一个地址,才能取出来。
不过,创建hash
的时候,我们也能够自己指定比对方法。
(setf h (make-hash-table :test #'equal))
(setf (gethash '(1 2 3) h) '(4 5 6))
(gethash '(1 2 3)); (4 5 6)