【发布时间】:2017-10-23 21:56:44
【问题描述】:
我需要将结果中没有重复元素的两个列表相加(即联合)。 例如:
?- union([3,4,c,5], [7,f,c,3], X).
X = [3, 4, c, 5, 7, f].
基本思想似乎是获取列表 A 的每个元素并在执行此操作时将它们添加到输出中。
列表 A 为空后,遍历列表 B,只添加那些也不在列表 A 中的元素。
到目前为止,我所拥有的是:
union([],[],[]).
union(List1,[],List1).
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
这个谓词将
使用空列表调用它时会产生一个空列表,
在使用空 List2 调用它时导致 List1 和
使用列表递归将所有 List1 元素传递到输出。
我遇到的问题是检查 List2 的元素是否也在 List1 中。
我的尝试:
union(List1, [Head2|Tail2], [Head2|Output]):-
not(member(Head2,List1)), union(List1,Tail2,Output).
union(List1, [Head2|Tail2], Output):-
member(Head2,List1), union(List1,Tail2,Output).
这并没有导致正确的答案。我认为这是因为当程序到达
not(member(Head2,List1))
此时 List1 将是空的,因为
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
这意味着 List2 的所有元素都会附加到输出中。
如果在我检查时 List1 为空,我将如何检查 List2 的元素是否不在 List1 中?还是有其他解决方案可以解决整个问题?
【问题讨论】:
-
ISO 否定是
\+/1,而不是not/1 -
好吧,我改用了\+,但恐怕答案还是一样。
-
@T44v1:您可能会发现 this post 在联合列表中很有趣。
-
我可能会这样做:
union(X, Y, Z) :- setof(E, (member(E, X); member(E, Y)), Z).,因为如果你大声读出来,这听起来就像你的问题。 -
@Dan:
union([],[],[])的失败是故意的吗?