简体   繁体   English

统计 lisp 中的出现次数

[英]Count occurrences in lisp

I'm trying to make a code in lisp to count occurrences of atoms in a list in lisp.我正在尝试在 lisp 中编写代码来计算 lisp 列表中原子的出现次数。 The problem is the code works for all atoms except the atom () , which appears as NIL .问题是代码适用于除 atom ()之外的所有原子,它显示为NIL Example in the code:代码中的示例:

(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))

Any idea in how to show () rather than NIL ?关于如何显示()而不是NIL的任何想法?

The expressions nil , 'nil , () , and '() all gets evaluated to nil which is displayed as nil unless it is the cdr of a pair in which it will just close the list.表达式nil'nil()'()都被评估为nil ,它显示为nil ,除非它是它会关闭列表的一对的cdr eg.例如。 '((). ()) gets evaluated to (NIL. NIL) and it is displayed as (NIL) . '((). ())被评估为(NIL. NIL)并显示为(NIL) There is nothing you can do about that.你对此无能为力。

So the question is then, because ((a) (()) (c)) is really ((a. nil). ((nil. nil). ((c. nil). nil))) should it count nil / () 5 times or ignore when nil in the cdr of a pair and just count it as one?那么问题来了,因为((a) (()) (c))真的是((a. nil). ((nil. nil). ((c. nil). nil)))是否应该算nil / () 5 次或在一对的cdr中为nil时忽略并仅将其视为一个?

BTW using setq in countOccurencesAll on undefined bindings means your code is in the mercy of the implementation.顺便说一句,在未定义的绑定上在countOccurencesAll中使用setq意味着您的代码受实现的支配。 The hyperspec does not define how it should be handled and SBCL makes warnings about how it interprets the code and other might just choose an interpretation.超规范没有定义它应该如何处理,SBCL 会警告它如何解释代码,而其他人可能只是选择一种解释。 A better approach would be to use let to define the bindings.更好的方法是使用let来定义绑定。 Using a hash and iterate over the list once would make an O(n) solution.使用 hash 并遍历列表一次将产生 O(n) 解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM