我正在尝试制作两个列表的交集(即列表C包含那些,只有那些在A和B中的元素),但据我所知,我得到了2个列表的分离+任何数量的元素下进行。
打算像以下一样工作:
d(A,B,C) :- (member(X,D)->member(X,A),member(X,B)).
你能告诉我:我的句子和谓词不相同还是我犯了另一个错误?
示例:
?- [user].
|: d(A,B,C) :- (member(X,D)->(member(X,A),member(X,B))).
|: % user://1 compiled 0.01 sec, 612 bytes
true.
?- d([a,b],[b,c],C)
| .
C = [b|_G21] .
?- d([a,b],[b,c],[b]).
true .
答案 0 :(得分:1)
删除了重复项的O(NlogN)
解决方案:
% untested
intersection(A, B, O) :-
sort(A, AS),
sort(B, BS),
intersection1(AS, BS, O).
intersection1(A, B, O) :-
( A = [AH|AT],
B = [BH|BT]
-> ( AH == BH
-> O = [AH|OT],
intersection1(AT, BT, OT)
; ( AH @< BH
-> intersection1(AT, B, O)
; intersection1(A, BT, O) ) )
; O = [] ).
答案 1 :(得分:1)
我喜欢@salva提出的解决方案,虽然我会做一个更简单的排序和合并,但却放弃了任何不匹配的东西:
intersect( As , Bs , Cs ) :-
sort( As , SortedAs ) ,
sort( Bs , SortedBs ) ,
merge( SortedAs , SortedBs , Cs )
.
merge( [] , [] , [] ).
merge( [] , [_|_] , [] ).
merge( [_|_] , [] , [] ).
merge( [C|As] , [C|Bs] , [C|Cs] ) :- merge( As , Bs , Cs ) .
merge( [A|As] , [B|Bs] , Cs ) :- A @< B , merge( As , [B|Bs] , Cs ) .
merge( [A|As] , [B|Bs] , Cs ) :- A @> B , merge( [A|As] , Bs , Cs ) .
答案 2 :(得分:0)