common-lisp - 在 SBCL 中为自定义散列表定义散列函数
问题描述
SBCL 手册说可以使用以下宏来定义自定义哈希表的测试:
(sb-ext:define-hash-table-test ht-equality-fn ht-hash-fn)
whereht-equality-fn
确定两个键是否相同,并ht-hash-fn
确定一个键的哈希值。
在这种特殊情况下,键本身是结构(用 定义defstruct
),其中包含一个带有固定编号键和 T 值(表示固定编号集)的哈希表的槽。
如果我正确理解了 SBCL 要求,那么直接编写的ht-equality-fn
方法似乎是:
(defun ht-equality-fn (key1 key2)
(equalp (ht-accessor key1) (ht-accessor key2))
但我不知道如何编写哈希函数来获得非负的 fixnum 哈希码:
(defun ht-hash-fn (ht)
???)
起初我想使用sxhash
,但超规范说这仅适用于equal
键(不是equalp
,这是哈希表相等测试所必需的)。感谢您的任何帮助。
解决方案
一个快速而简单的哈希函数代码是简单地将输入 ht 中的 fixnum 键相加,因为对于任何 fixnums 的排列,总和都是相同的。对于这个问题,事实证明,ht fixnums 都明显小于most-positive-fixnum
,因此总和不应超过最大值。然而,最坏情况下的散列性能可能不足,因为许多不同的固定数集可以总和为相同的值。
(defun ht-hash-fn (ht)
(declare (hash-table ht))
(let ((sum 0))
(declare (fixnum sum))
(maphash (lambda (key value)
(declare (fixnum key) (ignore value))
(incf sum key))
ht)
sum))
推荐阅读
- ruby-on-rails - Rspec - 存根块并测试生成的主体的更好方法
- powershell - 如何在powershell脚本结束时自动停止所有启动的进程
- oracle-apex - Oracle Apex - 通过验证和交互式网格的日期有效非重叠日期 - 如何引用交互式网格当前行值
- flask - Flask:尝试在公共文件夹中获取图像文件存储时出错 - 404 Not Found
- javascript - 如何使用 JavaScript 计算 Flex 容器内元素之间的距离 JavaScript
- c - 使用 bindgen 绑定基于 TPM 的服务的 tbs.h 时出现“未知类型名称”
- r - Windows上的r drake文件路径搞砸了
- python - 有没有办法让 tkinter 在相互添加两个变量时显示不同的标签
- css - 希望方形空间中的辅助导航栏位于底部 - 与主导航栏分开
- angular - 装饰可注入角度服务的正确方法