【问题标题】:Making a union of two lists in prolog在 prolog 中合并两个列表
【发布时间】: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([],[],[]) 的失败是故意的吗?

标签: list prolog


【解决方案1】:

好吧,似乎union中元素的顺序无关紧要,所以我稍微更改了代码:

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).  

此谓词将通过 List2,将所有不在 List1 中的元素附加到输出,一旦 List2 为空,会将整个 List1 附加到输出。
在这种情况下:

?- union([3,4,c,5], [7,f,c,3], X).

会得到我

X = [7, f, 3, 4, c, 5].

这没关系,因为顺序在作业中并不重要。

【讨论】:

    猜你喜欢
    • 2016-01-12
    • 2013-02-07
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2012-03-20
    • 2011-04-25
    • 2021-10-07
    相关资源
    最近更新 更多