重复列表由元素(element,number_of_occurrences)组成。对于这样的两个元素列表找到交集。
我写了以下代码
min(X,Y,X):-X=<Y.
min(X,Y,Y):-X>Y.
search([X,Y],[[X,W]|_],[X,Z]):-min(Y,W,Z).
search([X,Z],[[_,_]|T],Answer):-search([X,Z],T,Answer).
intersection([],_,[]).
intersection([[H,O]|T],L2,[Z|Temp]):-
member([H,_],L2),
search([H,O],L2,Z),
intersection(T,L2,Temp).
intersection([H|T],L2,Temp):-
\+member(H,L2),
intersection(T,L2,Temp).
当我在此测试时:交叉点([[1,2],[2,2],[5,5]],[[1,1],[2,3],[4,5] ],一个)。 它给出A = [[1,1],[2,2]],A = [[1,1]]和A = [[2,2]] A = [] 我只想要第一个答案,我该怎么做?我的代码出了什么问题?
答案 0 :(得分:1)
我认为使用member/2
后跟search/3
会因回溯而创建子集解决方案。 search/3
谓词已经成功或失败,取决于其设计的成员资格。因此,如果您重新调用intersection/3
谓词,则可以消除冗余并强制执行完整解决方案。
您还可以删除min/3
谓词,注意SWI Prolog支持min/2
。您可以将min(Y, W, Z)
替换为Z is min(Y, W)
,但只是意识到假设Y
和W
始终都是实例化的。
search([X,Y], [[X,W]|_], [X,Z]) :- Z is min(Y, W).
search([X,Z], [_|T], Answer) :- search([X,Z], T, Answer).
intersection([], _, []).
intersection([[H,O]|T], L2, R) :-
( search([H,O], L2, Z)
-> R = [Z|Temp]
; R = Temp
),
intersection(T, L2, Temp).
?- intersection([[1,2],[2,2],[5,5]], [[1,1],[2,3],[4,5]], A).
A = [[1, 1], [2, 2]].
?-