【发布时间】:2014-10-14 18:32:43
【问题描述】:
我有两个包含歌曲名称和歌手的列表——欧盟前 10 名和美国前 10 名。结果应该是一个包含两个列表中的歌曲的列表。
以下是设置列表的谓词:
top10us([
song(all_About_That_Bass, "Meghan Trainor"),
song(shake_It_Off, "Taylor Swift"),
song(black_Widow, "Iggy Azalea Featuring Rita Ora"),
song(bang_Bang, "Jessie J, Ariana Grande & Nicki Minaj"),
song(anaconda, "Nicki Minaj"),
song(habits, "Tove Lo"),
song(dont_Tell_Em, "Jeremih Featuring YG"),
song(animals, "Maroon 5"),
song(stay_With_Me, "Sam Smith"),
song(break_Free, "Ariana Grande Featuring Zedd")
]).
top10eu([
song(prayer_In_C, "Lilly Wood & Prick"),
song(lovers_On_The_Sun, "David Guetta & Sam Martin"),
song(chandelier, "Sia"),
song(rude, "Magic!"),
song(stay_With_Me, "Sam Smith"),
song(maps, "Maroon 5"),
song(all_Of_Me, "John Legend"),
song(all_About_That_Bass, "Meghan Trainor"),
song(a_Sky_Full_Of_Stars, "Coldplay"),
song(bailando, "Enrique Iglesias")
]).
这是我编写谓词的两次尝试。
尝试 1:
member(ITEM,[song(ITEM,_)|_],1).
member(_,[],0).
member(ITEM,[_|T],R):-
member(ITEM,T,R).
both([],[],[]).
both([song(NAME,_)|T1], L2,[NAME|T3]):-
member(NAME,L2,R),R=1,both(T1, L2, T3).
both([_|T], L2, T3):-
both(T, L2, T3).
?- top10eu(L1),top10us(L2),both(L1,L2,RESULT),write(RESULT). // the result is false here
尝试 2:
both(_,[],[],[]).
both(ORIGINAL,[_|T],[],OUTPUT):-
both(ORIGINAL,T,ORIGINAL,OUTPUT).
both(ORIGINAL, [song(NAME,SINGER)|T1], [song(NAME,_)|T2],[NAME|T3]):-
both(ORIGINAL, [song(NAME,SINGER)|T1], T2, T3).
both(ORIGINAL, L1, [_|T2], T3):-
both(ORIGINAL, L1, T2, T3).
?- top10eu(L1),top10us(L2),both(L1,L1,L2,RESULT),write(RESULT). // here a list is returned, but with wrong elements.
我在墙上挂了几个小时,无法解决这个问题。更深入prolog的人可以看看吗?我认为这不是太具体,因为主要问题是如何获取两个列表中存在的值。
编辑:我的第二次尝试恰好在工作,但我用错误的参数列表调用它。用?- top10eu(L1),top10us(L2),both(L2,L1,L2,RESULT),write(RESULT). 调用它会返回正确的列表:RESULT = [stay_With_Me, all_About_That_Bass]
不管怎样,有没有更优雅的方法呢?
【问题讨论】:
-
top10eu(L1), top10us(L2), findall(Song, (member(Song, L1), member(Song, L2)), Songs)怎么样? -
还有 intersect/3...
-
@DanielLyons:哇!我不知道 findall() 和 member()。它做得很棒,但是如何在没有艺术家的情况下获得歌曲名称?结果必须是
[stay_With_Me, all_About_That_Bass]。您可以将此作为答案发布,以便我选择它吗? -
@CapelliC:我正在使用 swi-prolog 解释器,并且有
intersection/3。与丹尼尔的评论相同的问题 - 我怎样才能得到歌曲名称? -
使用 findall,比交集更容易: ... findall(Song, (E = song(Song,_), member(E, L1), member(E, L2)), Songs)
标签: prolog