微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

确定位数组是否在位数组的集合中

如何解决确定位数组是否在位数组的集合中

考虑到二维Nxn位数组,我正在尝试评估确定位数组是否已经存在于以前见过的大量位数组中的最佳方法

一种直接的方法是将位数组放在哈希表中。但是比较数组需要一个#'equalp:test函数,这可能不是很有效。 (但是SBCL可能会自动针对不同的密钥类型进行优化吗?)

一个计划是将所有位数组转换为整数,并将整数放入哈希表中。然后测试可以是#'eql:

(defun bit-arr-to-int (bit-array)
  (reduce (lambda (bit1 bit2)
            (+ (* bit1 2) bit2))
          (make-array (array-total-size bit-array)
                      :displaced-to bit-array)))

但是,不确定这是否比让SBCL处理事情更有效,因为它仍然单独处理每个元素。也许定制的哈希表可以提供效率优势?

第三个选项可能涉及将基本表示形式从位数组更改为简单位矢量(又名整数),因为原始位数组的尺寸是已知的。为了允许等效于数组的元素引用,这将需要一个函数,该函数将隐式数组的行坐标转换为显式的简单位向量索引。如上所述,与按每次哈希表查找将整个位数组转换为整数相比,根据需要计算索引可能更有效。

欣赏一些经验丰富的见解。

解决方法

我认为了解这一点的唯一方法是尝试事物,看看最快的方法。

您可以尝试的一个可怕技巧是将位向量表示为(row-length . integer-of-bits)的缺点。您需要行长,以便可以以位整数形式计算偏移量。然后您可以执行以下操作(这些可能是错误的,因为我总是被dpbldb所迷惑):

(deftype index ()
  `(integer 0,most-positive-fixnum))

(defun make-bv (columns)
  (declare (type index columns))
  (cons columns 0))

(defun bv-ref (bv row column)
  (declare (type (cons index integer) bv)
           (type index row column))
  (let ((columns (car bv)))
    (assert (< column columns) (column) "column out of range")
    (ldb (byte 1 (+ (* row columns) column)) (cdr bv))))

(defun (setf bv-ref) (bit bv row column)
  (declare (type bit bit)
           (type (cons index integer) bv)
           (type index row column))
  (let ((columns (car bv)))
    (assert (< column columns) (column) "column out of range")
    (setf (cdr bv) (dpb bit (byte 1 (+ (* row columns) column)) (cdr bv)))
    bit))

在现实生活中,您当然想内嵌这些内容。

像这样的表示形式可能对散列很有用(您可以仅对equal进行散列,甚至在缺点中为两个元素嵌套eql散列表),但存在一个明显的问题,即它不能不必关心对象有多少行:它们本质上都具有无限制的行数。

如果'arrays'非常大并且您对其进行了很多更改,那会很糟糕,因为每次更改时都会浪费一个新的bignum。

但是我认为了解 的唯一方法是测量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。