Lisp 中的函数

function in Lisp

我正在尝试自学 Lisp 编程语言。我需要帮助定义 函数计算第二个列表中也出现在第一个列表中的元素。

(defun increasing-sum(list)
 (sort list #'(lambda (sublist1 sublist2)
 (< (apply #'+ sublist1 ) (apply #'+ sublist2)))))

很难从你的描述中看出,但听起来你只需要展平你的列表,计算交集,并取交集的总和,然后乘以二,因为交集中的每个元素会出现在每个列表中。您可以将其分解为 flatten 函数,然后使用标准库函数计算交集、求和和积。

(defun flatten (list)
  "Return a list of the non-null leaves of LIST, treated
as a tree of cons cells."
  (cond
   ((null list) list)
   ((atom list) (list list))
   ((append (flatten (first list))
            (flatten (rest list))))))

(flatten '(8 1 (4)))
;=> (8 1 4)

(flatten '(5 (1 (8)) 8 ))
;=> (5 1 8 8)

(defun sum (list1 list2)
  "Flatten LIST1 and LIST2, take their intersection, 
compute the sum over the intersection, and multiply by
two (since each element must have appeared in each list)."
  (* 2 (reduce '+ (intersection (flatten list1)
                                (flatten list2)))))

当然,问题在于使用此算法,您的示例的交集将为 (8 1),这将为您提供 18 ,不是 17,结果是:

(sum '(8 1 (4)) '(5 (1 (8)) 8))
;=> 18

也许您只是想计算第二个列表中同时出现在第一个列表中的元素的总和。在这种情况下,您可以使用稍微不同的算法。只需将树展平并计算第一个参数中不存在的第二个参数的元素的总和。请注意,这实际上不会将参数视为 sets,因为 sets 没有重复元素。这得到了您提到的 17 答案。

(defun sum2 (list1 list2)
  (let ((set1 (flatten list1)))
    (flet ((in-set-1-p (x)
             (member x set1)))
      (reduce '+ (remove-if-not #'in-set-1-p (flatten list2))))))
(sum2 '(8 1 (4)) '(5 (1 (8)) 8))
;=> 17