List 查找Prolog列表元素的组合/子列表
我正在尝试编写一个函数,该函数将通过删除1或2个元素(包括拆分列表)来生成列表元素的组合 例如:List 查找Prolog列表元素的组合/子列表,list,prolog,List,Prolog,我正在尝试编写一个函数,该函数将通过删除1或2个元素(包括拆分列表)来生成列表元素的组合 例如: [b,b,b] 可能成为 [b,b] [b] [[b],[b]] 我可以使用以下谓词生成前两个谓词: permute([_|T],T). permute([_|[_|T]],T). 但事实证明,第三个问题更加困难。我可以使用append将列表分成两部分,但我不知道如何将其与我已有的内容结合起来 我正在使用SWI Prolog (虽然被标记为家庭作业,但这是一个更大作业的一部分,也是我目前所处的
[b,b,b]
可能成为
[b,b]
[b]
[[b],[b]]
我可以使用以下谓词生成前两个谓词:
permute([_|T],T).
permute([_|[_|T]],T).
但事实证明,第三个问题更加困难。我可以使用append
将列表分成两部分,但我不知道如何将其与我已有的内容结合起来
我正在使用SWI Prolog
(虽然被标记为家庭作业,但这是一个更大作业的一部分,也是我目前所处的困境)谓词
permute([_|T],T).
permute([_|[_|T]],T).
将更恰当地命名为tail\u或\u tail的\u tail\u
。您是否注意到它只能删除第一个或前两个元素?如果您想去掉任意两个元素,请使用
take_out_one_or_two(L, R) :- select(_, L, R).
take_out_one_or_two(L, R) :- select(_, L, L1), select(_, L1, R).
您是对的,拆分可以通过append/3
完成。你(相当奇怪)的要求得到了满足
strange_predicate(L, R) :- take_out_one_or_two(L, R).
strange_predicate(L, [X,Y]) :- take_out_one_or_two(L, L1), append(X, Y, L1).
如果不希望结果中出现空列表,请将第二个子句替换为
strange_predicate(L, [X,Y]) :-
take_out_one_or_two(L, L1),
X = [_|_],
Y = [_|_],
append(X, Y, L1).
(如果没有用例,我真的想不出这个谓词的名称。)以Kayles的游戏为例,我们的应用表明一个经济的状态表示应该是一个正整数的有序列表,每个数字代表一个连续的瓶子串 我之所以说有序,是因为在这些值的任何排列下,游戏的状态都是等价的 因此,可能的行动包括选择一个条目,并将其减少一个或两个,变成零,一个或两个较小的条目。这些较小的条目(如果有的话)应该被插入到游戏状态列表的新“尾部”的适当位置 游戏动作更大的表现形式的一个组成部分是决定一个连续的X瓶串可以减少多少种方式。因此,我们可以从这一要求开始:
bowls(X,[ ]) :-
( 0 is X - 1 ; 0 is X-2 ).
bowls(X,[W]) :-
( W is X - 1 ; W is X-2 ),
W > 0.
bowls(X,[Y,Z]) :-
( W is X - 1 ; W is X-2 ),
W > 1,
bowlsplits(W,Y,Z).
读者可以使用Y>=Z>0产生Y+Z=W
的所有可能性来实现bowlsplits/3
请注意,使用这种表示法时,我们应该跳过与列表中的下一个条目相等的任何条目,以避免重复结果,因为两个相等的条目产生相同的可能结果
kayles([X],R) :- bowls(X,R).
kayles([X,Y|T],R) :-
X > Y,
bowls(X,L),
inSort(L,[Y|T],R).
kayles([X,X|T],[X|L]) :-
kayles([X|T],L).
读者还可以按照插入排序的方式在rt/3中实现,插入排序将前两个参数中的有序列表合并到一个有序列表中,以绑定第三个参数
请注意,kayles/2是尾部递归但不确定的。这些不是排列,所以请不要这样称呼它们。它们有正确的术语吗?(变体/子列表?)!这是针对Kayles的游戏,列表元素表示可以一组或两组打翻的瓶子,因此出现了奇怪的要求,一组可以分成两半。由于所有元素都是相同的,从开始或结束删除元素没有什么区别,但是感谢更新的谓词。@dig412:如果所有元素都是相同的,那么您就不需要列表了。一个整数计数器或一对Elem+Count
(例如b+3
)就足够了。这可以工作,它肯定会简化一些列表操作。我仍然习惯于Prolog,这是一种非常不同的编程方式。