计算两个列表的对称差异,并返回不包含重复项的第三个列表。
显示预期结果的示例查询:
?- join([a,b,p,l,a,f],[q,a,z,x,l],Rs).
Rs = [b,p,f,q,z,x].
我目前有这段代码:
join([],List,List).
join([H|T],List,[H|Result]) :-
not(member(H,List)),
join(T,List,Result).
join([H|T],Y,Z) :-
join(T,Y,Z).
它可以找到所有不重复的元素,但它将它们全部作为头部放在第二个列表中。
我怎样才能这样做,以便第二个列表也检查重复的元素,只输出那些不重复的元素?
答案 0 :(得分:2)
您描述的“非交集”似乎是两组的对称差异,这是它们(非对称)集合差异的并集。可以使用SWI-Prolog subtract/3
谓词或this problem解决方案计算差异。
可以使用append/3
后跟sort/2
来完成联合,后者会处理重复项。
答案 1 :(得分:1)
以下实施保留logical-purity。它基于:
tfilter/3
和tpartition/4
,if_/3
,not_t/3
,(=)/3
,list_setB/2
a previous answer。让我们直接看看代码!
list_list_symdiffset([],Ys,Zs) :-
list_setB(Ys,Zs).
list_list_symdiffset([X|Xs0],Ys0,Zs0) :-
tpartition(=(X),Ys0,Es,Ys1),
if_(Es=[], Zs0=[X|Zs1], Zs0=Zs1),
tfilter(not_t(=(X)),Xs0,Xs1),
list_list_symdiffset(Xs1,Ys1,Zs1).
让我们运行OP给出的示例查询:
?- list_list_symdiffset([a,b,p,l,a,f],[q,a,z,x,l],Rs).
Rs = [b,p,f,q,z,x]. % succeeds deterministically
最后,让我们尝试一些更通用的东西!
?- list_list_symdiffset([A,B],[X,Y],Ys).
Ys = [], A=B, B=X, X=Y ;
Ys = [B], A=X, X=Y, dif(Y,B) ;
Ys = [Y], A=B, B=X, dif(X,Y) ;
Ys = [], A=X, B=Y, dif(X,Y), dif(X,Y) ;
Ys = [B,Y], A=X, dif(X,B), dif(X,Y), dif(B,Y) ;
Ys = [X], A=B, B=Y, dif(Y,X) ;
Ys = [], A=Y, B=X, dif(Y,X), dif(Y,X) ;
Ys = [B,X], A=Y, dif(Y,B), dif(Y,X), dif(B,X) ;
Ys = [B,Y], A=B, X = Y, dif(B,Y), dif(B,Y) ;
Ys = [B,X,Y], A=B, dif(B,Y), dif(B,X), dif(X,Y) ;
Ys = [A], B=X, X=Y, dif(A,Y), dif(A,Y),dif(A,Y) ;
Ys = [A,Y], B=X, dif(A,X), dif(A,Y), dif(A,X), dif(X,Y) ;
Ys = [A,X], B=Y, dif(A,Y), dif(A,Y), dif(A,X), dif(Y,X) ;
Ys = [A,B,Y], X=Y, dif(A,B), dif(A,Y), dif(A,Y), dif(B,Y), dif(B,Y) ;
Ys = [A,B,X,Y], dif(A,B), dif(A,Y), dif(A,X), dif(B,Y), dif(B,X), dif(X,Y).
答案 2 :(得分:0)
join(L1,L2,L) :-
append(L1,L2,L3),
findall(A,unique(L3,A),L).
unique(L3,A) :-
append(L0,[A|R],L3),
\+(append(_,[A|_],L0)).