我将如何定义一个接受2个列表(l1 l2)并返回列表1中原子在列表2中出现的次数的函数。
答案 0 :(得分:0)
诀窍是遍历第二个列表,计算遇到的很多东西出现在第一个列表中。 member
函数可让您进行测试,因此最终可能会遇到以下两个选项之一:
;; A version with explicit recursion down the list
;;
;; This will blow its stack if list is too long.
(defun count-known-atoms (known list)
"Return how many of the elements of `list' are atoms and appear
in `known'."
(if (null list)
0
(let ((hd (car list)))
(+ (if (and (atom hd) (member hd known)) 1 0)
(count-known-atoms known (cdr list))))))
;; A version using local variables and side effects. Less pretty, if you're a
;; fan of functional programming, but probably more efficient.
(defun count-known-atoms-1 (known list)
"Return how many of the elements of `list' are atoms and appear
in `known'."
(let ((count 0))
(dolist (x list count)
(when (and (atom x) (member x known))
(setq count (1+ count))))))
;; (count-known-atoms '(1 2) '(0 1 2 3 4 5)) => 2
;; (count-known-atoms-1 '(1 2) '(0 1 '(2) 3 4 5)) => 1
如果ELisp具有sum
函数可对列表或某种fold
求和,则另一种选择是在第二个列表上进行映射以得到零和一,然后将其压缩下来。不过,我不认为这样做,所以建议使用count-known-atoms-1
。