我需要对结果中没有重复元素的两个列表进行求和(即并集)。例如:
?- union([3,4,c,5], [7,f,c,3], X).
X = [3, 4, c, 5, 7, f].
Run Code Online (Sandbox Code Playgroud)
基本思想似乎是获取列表 A 的每个元素并将它们添加到输出中。
列表 A 为空后,遍历列表 B 并仅添加那些不在列表 A 中的元素。
到目前为止,我所拥有的是:
union([],[],[]).
union(List1,[],List1).
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
Run Code Online (Sandbox Code Playgroud)
使用空列表调用此谓词
时将导致空列表,
使用空 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).
Run Code Online (Sandbox Code Playgroud)
这并没有得出正确的答案。我认为这是因为当程序达到
not(member(Head2,List1))
Run Code Online (Sandbox Code Playgroud)
此时 List1 将为空,因为
union([Head1|Tail1],List2,[Head1|Output]):-
union(Head1,List2,Output).
Run Code Online (Sandbox Code Playgroud)
这意味着 List2 的所有元素都会附加到输出中。
如果在检查时 List1 为空,我究竟如何检查 List2 的元素不在 List1 中?或者还有其他解决方案来解决整个问题吗?
好吧,似乎联合内元素的顺序并不重要,所以我稍微改变了代码:
union([],[],[]).
union(List1,[],List1).
union(List1, [Head2|Tail2], [Head2|Output]):-
\+(member(Head2,List1)), union(List1,Tail2,Output).
union(List1, [Head2|Tail2], Output):-
member(Head2,List1), union(List1,Tail2,Output).
Run Code Online (Sandbox Code Playgroud)
该谓词将遍历 List2,将不在 List1 中的所有元素附加到输出中,一旦 List2 为空,会将整个 List1 附加到输出中。
在这种情况下:
?- union([3,4,c,5], [7,f,c,3], X).
Run Code Online (Sandbox Code Playgroud)
会得到我
X = [7, f, 3, 4, c, 5].
Run Code Online (Sandbox Code Playgroud)
这没关系,因为顺序在作业中并不重要。