Prolog:在较小的单独列表中填写大列表

时间:2013-05-30 23:24:17

标签: prolog

我正在寻找机会将列表切割成较小的列表,例如:

[1,2,3,4] -> [[1,2],[2,3],[3,4]]
[1,2] -> [[1,2]]

依旧......

首先,我搜索了一个内置谓词的解决方案。但我无法弄明白与他们一起做..这是对的吗?! 所以我写了一个自己的谓词:

slice([],[]).
slice([H1,H2|T], Output) :-
    append([H2],T,New),
    slice(New, [[H1,H2]|Output]).

但是在最后一个迭代步骤中,当New只包含一个元素时,与[H1,H2 | T]的统一失败..

3 个答案:

答案 0 :(得分:2)

根据 mapadj/3Prolog lambdas一起定义slice/2!只需写下:

slice(Xs,Yss) :-
   mapadj(\X0^X1^[X0,X1]^true, Xs, Yss).

示例查询:

?- slice([1,2],Yss).
Yss = [[1,2]].

?- slice([1,2,3,4],Yss).
Yss = [[1,2],[2,3],[3,4]].

答案 1 :(得分:1)

基于@SergeyDymchenko的答案,很大程度上取决于您希望如何处理单个元素列表的特殊情况[1]

你丢弃它吗?

[1] --> []

如果是这样,谢尔盖的回答是正确的。

或者,您是否将其“切片”为单个元素的子列表,例如

[1] --> [ [1] ]

如果是这样,你需要修改谢尔盖答案的第二个词:

slice( []      , []            ) .
slice( [H]     , [ [H] ]       ) .
slice( [H1,H2|T] , [[H1,H2]|R] ) :-
  slice( [H2|T] , R )
  .

第三个alernative将简单地失败,将单个元素的列表视为谓词的无效输入:单个元素的列表不能分解为2个元素的子列表,每个子元素由相邻的对组成

只有你可以确定这个问题的真实语义。

答案 2 :(得分:0)

slice([], []).
slice([_], []) :- !.
slice([H1, H2 | T], [[H1, H2] | SliceT]) :-
    slice([H2 | T], SliceT).