2012-12-30 80 views
1

我有一个问题,我有两个列表,我想提取所有相同的元素。例如:Prolog - 在两个列表中提取元素列表

> 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]. 

但这个代码,我做不工作。我是新手,所以......问题是什么? :/

回答

2

您使用的是accumlator,所以代码应该是

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). 
+0

谢谢,它完美的作品^^所以如果成员是真的,LI = [X | R] ...被执行?我不知道“ - >”:/ – toshiro92

2

intersection/3不正是你需要的。

?- intersection([la_defense,etoile,chatelet,nation],[auber,chatelet,hotel_de_ville,nation],X). 
X = [chatelet, nation]. 
+0

我不明白你想解释什么? – toshiro92

+1

以防万一您不知道可用的库... IMO是有意义的,因为@ joel76已经解决了代码中的问题 – CapelliC

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;它迫使你在使用它时考虑声明性程序方面的