我有一个问题,我有两个列表,我想提取所有相同的元素。例如:
> comparer([la_defense,etoile,chatelet,nation],[auber,chatelet,hotel_de_ville,nation],X).
comparer([],LSB,LI).
comparer([X|LS],LSB,LI):-member(X,LSB),!,comparer(LS,LSB,[LI|X]).
comparer([X|LS],LSB,LI):-comparer(LS,LSB,LI).
我想要这个结果:
X = [chatelet,nation].
但是我制作的这段代码不起作用。我是新手所以...问题是什么? :/
答案 0 :(得分:2)
您正在使用累加器,代码应该是
comparer(L1, L2, R) :-
comparer(L1, L2, [], R).
comparer([], _, R, LR) :-
reverse(R, LR).
comparer([X|LS],LSB,LI, R):-
member(X,LSB),!,
comparer(LS,LSB,[X | LI], R).
comparer([_X|LS],LSB,LI, R):-
comparer(LS,LSB,LI, R).
你可以试试这个
comparer([], _, []).
comparer([X|LS],LSB,LI):-
comparer(LS, LSB, R),
( member(X, LSB) -> LI = [X | R]; LI = R).
答案 1 :(得分:2)
intersection / 3完全符合您的需要。
?- intersection([la_defense,etoile,chatelet,nation],[auber,chatelet,hotel_de_ville,nation],X).
X = [chatelet, nation].
答案 2 :(得分:1)
My answer对您可能感兴趣的类似问题Intersection and union of 2 lists。
与此处发布的其他答案和there不同,我建议的实现在逻辑上是纯粹的和单调的,这使得它在泛化/专业化方面更加通用和强大。
首先,让我们看看它是否适用于您在上面提供的查询:
?- As = [la_defense,etoile,chatelet,nation],
Bs = [auber,chatelet,hotel_de_ville,nation],
list_list_intersection(As,Bs,Xs).
As = [la_defense, etoile, chatelet, nation],
Bs = [auber, chatelet, hotel_de_ville, nation],
Xs = [chatelet, nation].
但是如果我们以不同的(但逻辑上等价的)方式编写查询呢?
?- As = [_,_,_,_],
Bs = [_,_,_,_],
list_list_intersection(As,Bs,Xs),
As = [la_defense,etoile,chatelet,nation],
Bs = [auber,chatelet,hotel_de_ville,nation].
As = [la_defense, etoile, chatelet, nation],
Bs = [auber, chatelet, hotel_de_ville, nation],
Xs = [chatelet, nation].
使用list_list_intersection/3
,我们得到相同的结果。
现在,让我们考虑使用另一个答案中提出的内置intersection/3
。 intersection/3
对于泛化也是健全的吗?
?- As = [_,_,_,_],
Bs = [_,_,_,_],
intersection(As,Bs,Xs),
As = [la_defense,etoile,chatelet,nation],
Bs = [auber,chatelet,hotel_de_ville,nation].
false.
否! intersection/3
失败,即使它在逻辑上等效的查询中成功,这表明intersection/3
的实现不是单调的 。
底线: intersection/3
比list_list_intersection/3
更难使用;它会强迫您在使用时考虑声明性和程序方面。