我发现自己越来越缩小(非常简单)的问题。
假设我有这个操作:listsplit([H1,H2,H3|T], H1,H2,H3, T).
这给了我列表的前三个元素。我想要一个程序,单元格,来传输一个输入列表,并对列表中的每个元素进行(至少一次操作!!)。
所以我有类似的东西:
cells(Input, Result):-
cellsBody(Input, [], Result).
cellsBody([],Result,Result).
cellsBody([Head|Input], Acc, [Headd|Result]):-
listsplit(Input,H1,H2,H3,_),
cellsBody(Input, [OutputBody|Acc], Result).
我有这个代码,因为我已经使用了许多我已经看过的例子,就像去旅行列表一样。他们将头部与身体分开并继续。我没有看到这是如何在prolog中完成的。我尝试更改变量名称,以便它们匹配(就像我在其他语言中所做的那样),并且我试图使问题尽可能简单。
那么,我如何旅行一个列表并对每个元素进行操作(我选择从第一个元素开始,即头部)。
编辑:我想要成就的例子:
我得到一个像oxo,oxxxo,oxoxo等的输入列表。然后我将规则应用于前三个元素,然后是接下来的三个,依此类推,当我这样做时,我将规则的结果添加到我返回的另一个列表中(这就是我尝试使用累加器的原因)
答案 0 :(得分:2)
你几乎得到了它。保持谓词单元格/ 2不变,首先考虑特殊情况:列表[]
,[_]
,[_,_]
没有三个元素,所以无论你想要什么操作这三个要素,在这些情况下无关紧要。否则,您有一个递归规则来执行您想要的操作。
查看listsplit / 5:您可以直接在递归规则的头部执行此操作,无需额外的谓词。然后,您有一个或多个目标用于您的预期操作。为了举个例子,我们假设将3个头元素打包为三元组。当然,关系也必须适用于列表的尾T
。然后你的代码看起来像这样:
cellsBody([],Result,Result).
cellsBody([_],Result,Result).
cellsBody([_,_],Result,Result).
cellsBody([H1,H2,H3|T], Acc, Result):- % the first 3 elements
Triplet=(H1,H2,H3), % at least ONE operation with them
cellsBody(T, [Triplet|Acc], Result).
示例查询:
?- cells([],Result).
Result = []
?- cells([1],Result).
Result = []
?- cells([1,2],Result).
Result = []
?- cells([1,2,3],Result).
Result = [(1,2,3)]
?- cells([1,2,3,4,5,6,7],Result).
Result = [(4,5,6),(1,2,3)]
当然,如果预期的操作与上面的示例一样简单,那么您不需要额外的目标:您可以直接在递归目标中执行此操作:
cellsBody([H1,H2,H3|T], Acc, Result):-
cellsBody(T, [(H1,H2,H3)|Acc], Result).