LISP - 创建向量
现代 Lisp:使用向量
Section titled “现代 Lisp:使用向量”**向量(vector)**是 Common Lisp 中的一维数组。与列表(lists)不同,列表优化了在头部添加/删除元素的操作,而向量通过索引提供了快速、常数时间(O(1))的任意元素访问。这使得它们非常适合随机访问数据存储。
创建向量的三种方式
Section titled “创建向量的三种方式”Common Lisp 提供了三种主要的创建向量的方式,每种都适用于不同的情况。
1. 使用 vector 函数
Section titled “1. 使用 vector 函数”当你在创建时就已知向量的元素时,可以使用 vector 函数。
;; 创建一个数字向量(vector 10 20 30) ; => #(10 20 30)
;; 创建一个混合类型的向量(vector "apple" 3.14 t) ; => #("apple" 3.14 T)2. 使用 #(...) 读取器宏
Section titled “2. 使用 #(...) 读取器宏”#(...) 语法是一种简洁的字面量方式来定义向量。它在代码编译之前由 Lisp 读取器(reader)进行求值,这使得它对于常量数据非常高效。
;; 读取器宏常用于常量向量(defparameter *my-constants* #(1 2 3))(defparameter *fruit* #("apple" "banana" "orange"))3. 使用 make-array 实现最大灵活性
Section titled “3. 使用 make-array 实现最大灵活性”make-array 是创建向量(以及多维数组)最强大的工具。它允许你指定大小、所有元素的初始值、元素类型,以及向量是否应该是可调整的。
;; 创建一个大小为 5,所有元素初始化为 0 的向量(make-array 5 :initial-element 0) ; => #(0 0 0 0 0)
;; 从一个包含初始内容的列表创建向量(make-array 3 :initial-contents '(1 2 3)) ; => #(1 2 3)
;; 创建一个只能存储字符串的专业化向量(make-array 4 :element-type 'string :initial-element "empty"); => #("empty" "empty" "empty" "empty")可调整向量和填充指针
Section titled “可调整向量和填充指针”对于需要动态、可增长数组(如 C++ 中的 std::vector 或 Java 中的 ArrayList)的情况,你可以创建一个带填充指针的可调整向量。
:fill-pointer 跟踪活动元素的数量,而 :adjustable t 允许向量在空间不足时进行调整大小。你可以使用 vector-push-extend 添加元素。
main.lisp
Section titled “main.lisp”;; 创建一个初始容量为 5 的动态向量(defparameter *dynamic-vector* (make-array 5 :adjustable t :fill-pointer 0))
(print *dynamic-vector*)(format t "Initial length (fill-pointer): ~a~%" (fill-pointer *dynamic-vector*))
;; 向向量中添加元素(vector-push-extend 'a *dynamic-vector*)(vector-push-extend 'b *dynamic-vector*)
(print *dynamic-vector*)(format t "New length (fill-pointer): ~a~%" (fill-pointer *dynamic-vector*))
;; 使用 AREF 访问元素(format t "First element: ~a~%" (aref *dynamic-vector* 0))执行这段代码会演示整个过程:
#()Initial length (fill-pointer): 0#(A B)New length (fill-pointer): 2First element: A最佳实践:列表与向量
Section titled “最佳实践:列表与向量”- 使用列表(Lists)的场景: 栈(Stacks)、顺序处理,以及当你频繁地在集合开头添加或删除元素时。它们的优势在于
cons、first和rest等操作。 - 使用向量(Vectors)的场景: 通过索引进行随机访问、固定大小的集合,或者你通常在末尾添加元素的动态数组。它们的优势在于
aref操作。