0

我正在尝试在 lisp 中编写代码来计算 lisp 列表中原子的出现次数。问题是代码适用于除 atom 之外的所有原子(),它显示为NIL. 代码中的示例:

(defun flatten (list_) 
    (cond   ((atom list_) (list list_))
            ((null list_) NIL)
            (t (append (flatten (car list_)) (flatten (cdr list_))) )
    )
)

(defun toUniqueList (list_ out) 
    (cond   ((null list_) NIL)
            ((not (member (car list_) out)) (append (list (car list_)) (toUniqueList (cdr list_) (append (list (car list_)) out)) ))
            (t (toUniqueList (cdr list_) out))
    )
)

(defun countOccurences (list_ x) 
    (cond   ((null list_) 0)
            ((eql (car list_) x) (+ (countOccurences (cdr list_) x) 1))
            (t (countOccurences (cdr list_) x))
    )

)

(defun countOccurencesAll (list_) 
    (setq flatList (flatten list_))
    (setq parsed (toUniqueList flatList '()))
    (setq result '())
    (dolist (x parsed)
        (setq result (append result (list (list x (countOccurences flatList x)) ))))
    result
)

(write (countOccurencesAll '(x y z 4.6 (a x) () (5 z x) ())))
; ((X 3) (Y 1) (Z 2) (4.6 1) (A 1) (NIL 5) (5 1))

关于如何展示()而不是展示的任何想法NIL

4

1 回答 1

1

表达式nil, 'nil, (), 和'()all 被评估为nilwhich 被显示为,nil除非它是cdr它会关闭列表的一对中的。例如。'(() . ())被评估(NIL . NIL)并显示为(NIL). 你对此无能为力。

那么问题来了,因为((a) (()) (c))它真的((a . nil) . ((nil . nil) . ((c . nil) . nil)))应该计算nil/ ()5 次,还是nilcdr一对中忽略它,只将它计算为一个?

顺便说一句,在未定义的绑定上使用setqincountOccurencesAll意味着您的代码受实现的支配。超规范没有定义它应该如何处理,SBCL 就它如何解释代码发出警告,其他人可能只是选择一种解释。更好的方法是使用let来定义绑定。使用散列并遍历列表一次将产生 O(n) 解决方案。

于 2021-01-02T03:28:04.927 回答