2012-03-13 31 views
0

我试图让程序在序言会做这样的事情:序言列出区别

diffSet([a,b,c,d], [a,b,e,f], X). 
X = [c,d,e,f] 

我写了这个:

diffSet([], _, []). 
diffSet([H|T1],Set,Z):- member(Set, H), !, diffSet(T1,Set,Z). 
diffSet([H|T], Set, [H|Set2]):- diffSet(T,Set,Set2). 

但这种方式,我只能从要素第一个列表。我如何从第二个元素中提取元素?

@edit: 件检查,如果H是集

member([H|_], H). 
member([_|T], H):- member(T, H). 

回答

2

有一个builtin从列表中删除元素:

diffSet([], X, X). 

diffSet([H|T1],Set,Z):- 
member(H, Set),  % NOTE: arguments swapped! 
!, delete(T1, H, T2), % avoid duplicates in first list 
delete(Set, H, Set2), % remove duplicates in second list 
diffSet(T2, Set2, Z). 

diffSet([H|T], Set, [H|Set2]) :- 
diffSet(T,Set,Set2). 
+0

你为什么要从第二个列表中删除重复项,但不是从第一个列表中删除重复项? – false 2012-03-13 21:17:33

+0

@false:删除(T1,H,T2)应该工作,我认为 – CapelliC 2012-03-13 21:28:03

0

在故意回避这个的内置插件@ chac提到,这是做这项工作的一种不雅的方式。

notcommon([], _, []). 

notcommon([H1|T1], L2, [H1|Diffs]) :- 
    not(member(H1, L2)), 
    notcommon(T1, L2, Diffs). 

notcommon([_|T1], L2, Diffs) :- 
    notcommon(T1, L2, Diffs). 

alldiffs(L1, L2, AllDiffs) :- 
    notcommon(L1, L2, SetOne), 
    notcommon(L2, L1, SetTwo), 
    append(SetOne, SetTwo, AllDiffs). 


    ? alldiffs([a,b,c,d], [a,b,e,f], X). 
    X = [c, d, e, f] . 
0

或者只使用内建。如果你想完成这项工作:

notcommon(L1, L2, Result) :- 

    intersection(L1, L2, Intersec), 
    append(L1, L2, AllItems), 
    subtract(AllItems, Intersec, Result). 

    ?- notcommon([a,b,c,d], [a,b,e,f], X). 
    X = [c, d, e, f].