计算lisp中的出现次数



我正试图在lisp中编写一个代码,以计算lisp中列表中原子的出现次数。问题是,该代码适用于除原子()(显示为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吗?

表达式nil'nil()'()都被求值为nil,CCD_9显示为nil,除非它是一对中的cdr,否则它将关闭列表。例如CCD_ 12被评估为CCD_。你对此无能为力。

那么问题是,因为((a) (()) (c))真的是((a . nil) . ((nil . nil) . ((c . nil) . nil))),它应该将nil/()计数5次,还是当nil在一对的cdr中时忽略,只将其计数为一?

BTW在未定义的绑定上使用countOccurencesAll中的setq意味着您的代码由实现决定。hyperspec没有定义应该如何处理它,SBCL对它如何解释代码发出警告,其他人可能只是选择一种解释。更好的方法是使用let来定义绑定。使用散列并在列表上迭代一次将生成O(n(解决方案。

相关内容

  • 没有找到相关文章

最新更新