我正在寻找机会将列表切割成较小的列表,例如:
[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]的统一失败..
答案 0 :(得分:2)
根据meta-predicate mapadj/3
与Prolog 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).