2016-11-20 86 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