继续上一篇关于交集(How to take intersection of pairs from two lists in scheme?)的帖子,我已经为同一行的联合编写了一个小代码。输出应该是:( union'((1 2)(2 1))'((1 3)(3 4))) - '((1 5)(2 1)(3 4))。但是,我的程序输出并不是我想要的。我认为我的递归或条件需要一些指导。请帮忙。感谢。
(define union
(lambda (set1 set2)
(let ((newlist '()))
(cond ((null? set1) set2)
((null? set2) set1)
((eq? (caar set1) (caar set2))
(append newlist (cons (caar set1) (+ (cadr (car set1))(cadr (car set2))))))
(else
(if (> (caar set1) (caar set2))(append newlist (car set1)) (union (cdr set1) set2))
(union set1 (cdr set2)))))))
答案 0 :(得分:1)
1)eq?
仅当两个参数完全相同的对象时才返回true。如果您只是比较数字,则需要使用equal?
或=
。
2)即使你的递归,无论你做什么,newlist
都是空的。您只是在最后两种情况下附加一个空列表。
3)这实际上不是联盟。当'(1 2)
和'(1 3)
成为'(1 5)
时,您正在寻找一些特殊行为。
然而,这就是你想要的。考虑到您投放了<
和>
并且各个集合中没有重复项(例如'((1 2) (1 2) (3 4))
:
(define (union set1 set2)
(cond [(empty? set1) set2]
[(empty? set2) set1]
[(equal? (car set1) (car set2)) (cons (car set1)
(union (cdr set1) (cdr set2)))]
[(= (caar set1) (caar set2)) (cons (list (caar set1)
(+ (cadar set1)
(cadar set2)))
(union (cdr set1) (cdr set2)))]
[(< (caar set1) (caar set2)) (cons (car set1) (union (cdr set1)
set2))]
[else (cons (car set2) (union set1
(cdr set2)))]))
逻辑:
1)其中一个是空的吗?如果是,请返回相应的设置。
2)一组中的第一个列表是否等于另一组中的第一个列表?如果是这样,(cons)
将共享列表传递给将两个集合的其余部分传递回联合的结果。
3)两个集合的第一个列表中的第一个元素是否相等?如果是这样,(cons)
包含公共第一个元素的列表和第二个元素的总和,将两个集合的其余部分传递回联合的结果。
4)最后两步执行与第一步类似的操作。将带有较小的第一个元素(cons)
的集合带到传递两个集合的结果上,减去刚刚提取的列表,然后再回到并集中。
您可以使用重复上的绑定本地定义进行优化,但希望这可以让您了解问题以及可能出错的地方。