我试图用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
将显示为nil
,除非它是cdr
一对将在其中只是关闭列表。例如。'(() . ())
被评估为(NIL . NIL)
,并显示为(NIL)
。您对此无能为力。
那么问题来了,因为((a) (()) (c))
它真的((a . nil) . ((nil . nil) . ((c . nil) . nil)))
应该计数nil
/ ()
5次还是nil
在cdr
成对出现时忽略而只是将其视为一个?
BTWsetq
在countOccurencesAll
未定义的绑定上使用in意味着您的代码受实施的影响。hyperspec并未定义应如何处理,SBCL会就其如何解释代码发出警告,而其他人可能只是选择一种解释。更好的方法是使用let
定义绑定。使用散列并遍历列表一次将构成O(n)解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句