2016-11-20 88 views
1

所以我正在做一個倒計時遊戲,我想檢查列表是否包含另一個列表的元素。涵蓋兩個列表的謂詞

鑑於兩個列表,檢查第二清單是否涵蓋了第一,那就是它會檢查每一個發生K次在第一個列表項是否也發生在第二至少K倍:

例子

我有一篇論文給了我很多練習的例子,到目前爲止我已經做得很好,但是這篇文章讓我有點躊躇。

我寫了這個,

cover([],_). 
cover([Head|Tail], List2):- 
    member(Head, List2), 
    cover(Tail, List2). 

問題是,它沒有考慮的列表次K個,

我一直在抓我的頭幾個小時, 任何指針將很棒。

回答

2

你是非常接近一個解決方案!

要完全解決這個問題,考慮有輕微概括member/2:我們在這種情況下使用的積木是很多像member/2,但具有下列扭曲:我們讓第三 參數表示什麼剩餘列表 是,我的意思是列表沒有  「member」。

傳統上,這個謂詞被稱爲select/3,這是一個非常糟糕的名字,因爲它表明我們只能在一個方向上使用謂詞。這是勢在必行

我會用一個更具描述性的,聲明名和調用這個selection/3

想想這關係這樣的:

 
selection(E, [E|Ls], Ls). 
selection(E, [L|Ls], [L|Rest]) :- 
     selection(E, Ls, Rest). 

你能想到的member/2作爲selection/3一個特例,因爲我們可以在selection/3來定義member/2,不關心剩餘 列表:

 
member(E, Ls) :- selection(E, Ls, _). 

使用selection/3,我們可以這樣寫:

 
list_cover([], _). 
list_cover([L|Ls], Cs0) :- 
     selection(L, Cs0, Cs), 
     list_cover(Ls, Cs). 

我們可以讀取第二條款如下:

如果LCs0的成員,並且是Cs剩餘列表(即,Cs0無  LCs覆蓋  Ls然後Cs0覆蓋  [L|Ls]

請注意命名約定,它理想地表明每個參數代表什麼。在我們的 的情況下,第二個的說法是覆蓋  列表。簡單地調用cover/2不會使 明確哪個參數實際上表示 封面。

樣品答問:

 
?- list_cover([a,e,i,o], [m,o,n,k,e,y,b,r,a,i,n]). 
true . 

?- list_cover([a,a,a], [a,a]). 
false. 

?- list_cover([a,a,a], [a,a,b,a]). 
true . 

並進一步:

 
?- list_cover(Ls, Cs). 
Ls = [] ; 
Ls = [_1900], 
Cs = [_1900|_1908] ; 
Ls = [_1900, _1912], 
Cs = [_1900, _1912|_1920]. 

很酷,不是嗎?這是相當一般的!

+1

多好的答案! – Enigmativity

+1

絕對的輝煌,謝謝你我的男人。 – Hidden