我在尝试调试此代码时无法找到两个列表之间的交集......
例如:
List1 = [3, 4, 5, 6]
和
List2 = [5, 1, 0, 2, 4]
。
因此,相交的行将存储到List3
[4, 5]
。
所以这里是Prolog的代码。
任何帮助将不胜感激!!!
setIntersection([], [], []).
setIntersection([], _, []).
setIntersection([X|Xs], Y, [Z|W]) :-
keepDuplicates(X, Y, [Z|Zs]),
setIntersection(Xs, Y, W).
keepDuplicates(_, [], []).
keepDuplicates([], _, []).
keepDuplicates([], [], []).
% Check if the head of the first list is not a match to the
% first head of the second list
keepDuplicates(G, [H|Hs], Line) :-
G \= H,
keepDuplicates(G, Hs, Line).
% Check if the head of the first list
% Does match to the head of the second list
keepDuplicates(G, [G|Gs], [G|NewLine]) :-
keepDuplicates(G, Gs, NewLine).
答案 0 :(得分:2)
您可以在my answer中找到与相关问题“Intersection and union of 2 lists”相关的几个逻辑纯的,单调的列表交集和联合实现。
让我们看一个示例查询:
?- list_list_intersection([3,4,5,6],[5,1,0,2,4],Intersection). Intersection = [4,5]. % succeeds deterministically
由于建议的实施方式是单调,您也可以通过更一般的方式使用它,并且仍能获得逻辑上合理的答案:
?- L2 = [_,_,_], list_list_intersection([3,4,5,6],L2,[4,5]).
L2 = [ 4, 5,_A], dif(_A,6), dif(_A,3) ;
L2 = [ 4,_A, 5], dif(_A,6), dif(_A,5), dif(_A,3) ;
L2 = [ 5, 4,_A], dif(_A,6), dif(_A,3) ;
L2 = [_A, 4, 5], dif(_A,6), dif(_A,5), dif(_A,4),dif(_A,3) ;
L2 = [ 5,_A, 4], dif(_A,6), dif(_A,4), dif(_A,3) ;
L2 = [_A, 5, 4], dif(_A,6), dif(_A,5), dif(_A,4),dif(_A,3) ;
false.
答案 1 :(得分:1)
Prolog中的sets
通常用排序列表表示,然后避免出现重复元素时出现的表示的歧义。我们忽略这个问题......
这个事实setIntersection([], [], []).
被setIntersection([], _, []).
包含,然后可以(应该!)被删除。
keepDuplicates([], [], []).
也一样(为什么你在这里反转条款?)
你有一个单身Zs:...,keepDuplicates(X, Y, [Z|Zs]),...
你应该注意那个警告(当然,如果你的编译器显示它),因为它经常是真正错误的症状。
此外,该谓词无法涵盖所有情况:当Y中的X 不时,您与Z相关联的是什么?
说实话,我认为你做的比实际要复杂得多。忽略重复,整体可以很容易
?- L1=[3,4,5,6],L2=[5,1,0,2,4],findall(C, (member(C,L1),memberchk(C,L2)), I).