3

我正在寻找机会将列表切成更小的列表,如下所示:

[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] 的统一失败..

4

3 回答 3

2

slice/2基于 mapadj/3Prolog lambdas一起定义!简单地写:

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]].
于 2015-08-13T09:39:10.563 回答
1

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

你丢弃它,这样

[1] --> []

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

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

[1] --> [ [1] ]

如果是这样,您需要修改 Sergey 答案的第二个术语:

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

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

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

于 2013-05-31T18:12:51.580 回答
0
slice([], []).
slice([_], []) :- !.
slice([H1, H2 | T], [[H1, H2] | SliceT]) :-
    slice([H2 | T], SliceT).
于 2013-05-31T00:37:02.240 回答