- LISP 教程
- LISP - 首页
- LISP - 概述
- LISP - 环境
- LISP - 程序结构
- LISP - 基本语法
- LISP - 数据类型
- LISP - 宏
- LISP - 变量
- LISP - 常量
- LISP - 运算符
- LISP - 决策
- LISP - 循环
- LISP - 函数
- LISP - 谓词
- LISP - 数字
- LISP - 字符
- LISP - 数组
- LISP - 字符串
- LISP - 序列
- LISP - 列表
- LISP - 符号
- LISP - 向量
- LISP - 集合
- LISP - 树
- LISP - 哈希表
- LISP - 输入与输出
- LISP - 文件I/O
- LISP - 结构体
- LISP - 包
- LISP - 错误处理
- LISP - CLOS
- LISP 有用资源
- Lisp - 快速指南
- Lisp - 有用资源
- Lisp - 讨论
Lisp - 哈希表
哈希表数据结构表示基于键的哈希码组织的键值对集合。它使用键来访问集合中的元素。
当您需要使用键访问元素,并且可以识别有用的键值时,可以使用哈希表。哈希表中的每个项目都具有键值对。键用于访问集合中的项目。
在LISP中创建哈希表
在 Common LISP 中,哈希表是一种通用的集合。您可以使用任意对象作为键或索引。
当您将值存储在哈希表中时,您会创建一个键值对,并将其存储在该键下。稍后,您可以使用相同的键从哈希表中检索该值。每个键只映射到一个值,尽管您可以将新值存储在同一个键下。
在 LISP 中,哈希表可以根据键的比较方式分为三种类型:eq、eql 或 equal。如果哈希表对 LISP 对象进行哈希,则键将使用 eq 或 eql 进行比较。如果哈希表对树结构进行哈希,则将使用 equal 进行比较。
make-hash-table 函数用于创建哈希表。此函数的语法如下:
make-hash-table &key :test :size :rehash-size :rehash-threshold
其中:
key 参数提供键。
:test 参数确定如何比较键 - 它应该具有三个值之一:#'eq、#'eql 或 #'equal,或三个符号 eq、eql 或 equal 之一。如果未指定,则假定为 eql。
:size 参数设置哈希表的初始大小。这应该是一个大于零的整数。
:rehash-size 参数指定当哈希表变满时增加哈希表大小的幅度。这可以是一个大于零的整数(要添加的条目数),也可以是一个大于 1 的浮点数(新大小与旧大小的比率)。此参数的默认值取决于实现。
:rehash-threshold 参数指定哈希表在必须增长之前可以达到多满。这可以是一个大于零且小于 :rehash-size 的整数(在这种情况下,每当表增长时都会对其进行缩放),也可以是一个介于零和 1 之间的浮点数。此参数的默认值取决于实现。
您也可以不带任何参数调用 make-hash-table 函数。
从哈希表中检索项目和向哈希表中添加项目
gethash 函数通过搜索其键来从哈希表中检索项目。如果找不到键,则返回 nil。
它的语法如下:
gethash key hash-table &optional default
其中:
key:是关联的键
hash-table:是要搜索的哈希表
default:如果未找到条目,则返回的值为 nil,如果未指定则为 nil。
gethash 函数实际上返回两个值,第二个值是一个谓词值,如果找到条目则为真,如果未找到条目则为假。
要向哈希表添加项目,您可以使用setf 函数以及gethash 函数。
示例
创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
main.lisp
; create a hashtable (setq empList (make-hash-table)) (setf (gethash '001 empList) '(Charlie Brown)) (setf (gethash '002 empList) '(Freddie Seal)) ; print the value for 001 from hashtable (write (gethash '001 empList)) ; terminate printing (terpri) ; print the value for 002 from hashtable (write (gethash '002 empList))
输出
执行代码时,它返回以下结果:
(CHARLIE BROWN) (FREDDIE SEAL)
删除条目
remhash 函数删除哈希表中特定键的任何条目。这是一个谓词,如果存在条目则为真,如果不存在条目则为假。
此函数的语法如下:
remhash key hash-table
示例
更新名为 main.lisp 的源代码文件,并在其中键入以下代码。
main.lisp
; create a hashtable (setq empList (make-hash-table)) (setf (gethash '001 empList) '(Charlie Brown)) (setf (gethash '002 empList) '(Freddie Seal)) (setf (gethash '003 empList) '(Mark Mongoose)) ; print the hash for 001 from hashtable (write (gethash '001 empList)) ; terminate printing (terpri) ; print the hash for 002 from hashtable (write (gethash '002 empList)) ; terminate printing (terpri) ; print the hash for 003 from hashtable (write (gethash '003 empList)) ; remove hash value (remhash '003 empList) ; terminate printing (terpri) ; print the hash for 001 from hashtable (write (gethash '003 empList))
输出
执行代码时,它返回以下结果:
(CHARLIE BROWN) (FREDDIE SEAL) (MARK MONGOOSE) NIL
maphash 函数
maphash 函数允许您将指定函数应用于哈希表上的每个键值对。
它接受两个参数 - 函数和哈希表,并为哈希表中的每个键值对调用一次函数。
示例
更新名为 main.lisp 的源代码文件,并在其中键入以下代码。
main.lisp
; create a hashtable (setq empList (make-hash-table)) (setf (gethash '001 empList) '(Charlie Brown)) (setf (gethash '002 empList) '(Freddie Seal)) (setf (gethash '003 empList) '(Mark Mongoose)) ; map hash on hashtable (maphash #'(lambda (k v) (format t "~a => ~a~%" k v)) empList)
输出
执行代码时,它返回以下结果:
3 => (MARK MONGOOSE) 2 => (FREDDIE SEAL) 1 => (CHARLIE BROWN)