lisp - 在 lisp 中计算出现次数
问题描述
我正在尝试在 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
?
解决方案
表达式nil
, 'nil
, ()
, 和'()
all 被评估为nil
which 被显示为,nil
除非它是cdr
它会关闭列表的一对中的。例如。'(() . ())
被评估(NIL . NIL)
并显示为(NIL)
. 你对此无能为力。
那么问题来了,因为((a) (()) (c))
它真的((a . nil) . ((nil . nil) . ((c . nil) . nil)))
应该计算nil
/ ()
5 次,还是nil
在cdr
一对中忽略它,只将它计算为一个?
顺便说一句,在未定义的绑定上使用setq
incountOccurencesAll
意味着您的代码受实现的支配。超规范没有定义它应该如何处理,SBCL 就它如何解释代码发出警告,其他人可能只是选择一种解释。更好的方法是使用let
来定义绑定。使用散列并遍历列表一次将产生 O(n) 解决方案。
推荐阅读
- phpstorm - 在 PhpStorm 中搜索实时模板
- javascript - 如何使用 ejs 和 node 制作模态框
- swift - 如何从 Swift 中的不同类调用函数?
- android - XING - 如何在 iOS 上的 Android 上进行深度链接?
- linux - 如何使用文件名中的通配符从 chown 递归中排除文件?
- linux - 循环内部中断的奇怪行为
- reflection - “控制器不存在。反思失败。” TYPO3 v2
- flutter - 如何在 PositionedTransition 小部件中放置一个可以正常工作的小部件
- python - 在 python 中读取单个命令后,串口被占用
- reactjs - 从 .env 文件中获取我的身份验证密钥,但它缺少字符