计算 lisp 中的出现次数
Count occurrences in 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
,显示为 nil
,除非它是一对中的 cdr
,它将关闭列表。例如。 '(() . ())
的计算结果为 (NIL . NIL)
,并显示为 (NIL)
。你对此无能为力。
那么问题来了,因为 ((a) (()) (c))
真的是 ((a . nil) . ((nil . nil) . ((c . nil) . nil)))
应该算 nil
/()
5 次还是在 nil
时忽略cdr
一对,算作一对吗?
顺便说一句,在未定义的绑定上使用 countOccurencesAll
中的 setq
意味着您的代码受实现的支配。 hyperspec 没有定义它应该如何处理,SBCL 就它如何解释代码发出警告,其他人可能只是选择一种解释。更好的方法是使用 let
来定义绑定。使用散列并遍历列表一次将生成 O(n) 解决方案。
我正在尝试用 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
一对,算作一对吗?
顺便说一句,在未定义的绑定上使用 countOccurencesAll
中的 setq
意味着您的代码受实现的支配。 hyperspec 没有定义它应该如何处理,SBCL 就它如何解释代码发出警告,其他人可能只是选择一种解释。更好的方法是使用 let
来定义绑定。使用散列并遍历列表一次将生成 O(n) 解决方案。