2015-08-15 82 views
0

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

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

+2

什么实际问题?还要注意Stackoverflow的这个用法提示:'重点关注您遇到的实际问题。包括你已经尝试过的内容以及你正在尝试做什么的细节。 –

+1

为什么你的例子返回17?我会说,将这些集合组合在一起产生了这个集合“(8 1(4)5)”,它给出了“8 + 1 + 4 + 5 = 18” – HyperZ

回答

2

这是艰难的,从你的描述说,但它听起来像你只需要汇整清单,计算交会,并采取交叉点的总和,然后再乘上两个,因为交叉点中的每个元素都会出现在每个列表中。您可以将其分解为拉平函数,然后使用标准库函数计算交点,和和乘积。

(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),并且会给你,不,如结果:

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

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

(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