如何对列表的每个元素进行操作

时间:2016-04-12 15:13:15

标签: prolog

我发现自己越来越缩小(非常简单)的问题。

假设我有这个操作: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等的输入列表。然后我将规则应用于前三个元素,然后是接下来的三个,依此类推,当我这样做时,我将规则的结果添加到我返回的另一个列表中(这就是我尝试使用累加器的原因)

1 个答案:

答案 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).