common-lisp - 从循环列表中删除自引用

标签 common-lisp circular-reference circular-list

我在 Common Lisp 中有一个复杂的循环数据结构:

(defvar xs '#1=(1 #2=(#1# 2 #3=(#2# 3 #4=(#3# 4 #1#)))))

如何将其转换为非循环列表,以便将每次出现的自引用替换为 nil?所以我没有 (1 (#0 2 (#1 3 (#2 4 #0)))) 我有 (1 (nil 2 (nil 3 (nil 4 nil)) ))

最佳答案

最简单的方法是了解使用哈希表遇到的所有缺点。即使在 cdr 中发生循环,此版本也能正常工作:

(defun remove-ref (list &optional (value nil))
  (let ((h (make-hash-table :test #'eq)))
    (labels ((rraux (list)
               (cond ((gethash list h) value)
                     ((not (consp list)) list)
                     (t (setf (gethash list h) t)
                        (cons (rraux (car list)) 
                              (rraux (cdr list)))))))
      (rraux list))))


(remove-ref '#1=(1 2 #2=(3 4 5 . #1#) 6 7 . #1#) 'test) 
; ==> (1 2 (3 4 5 . test) 6 7 . test)
(remove-ref '#1=(1 2 #2=(3 4 5 . #1#) 6 7 . #1#)) 
; ==> (1 2 (3 4 5) 6 7)

关于common-lisp - 从循环列表中删除自引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28973680/

相关文章:

lisp - 想学习普通的 lisp

package - 在 Common Lisp 中使用 iterate 包的正确方法

variables - lisp 中的变量问题

Facebook 调试器在某些网站上报告 "Circular redirect path detected"(301)

graphql - 使用循环引用动态创建 graphql 模式

java - 如何实现轮询循环链表并统计元素的访问请求?

oop - CLOS:方法与任意函数的组合

python - 处理来自 sys.exc_info() 的回溯对象时的适当注意和安全

java - next 无法解析为 java 中的值或字段

c - 为什么我的 C 循环双端队列程序无法退出打印功能?