[英]A prolog predicate to split a list into sperate lists ever n elements
The title is the required predicate and here are few sample queries标题是必需的谓词,这里有几个示例查询
?- splitEvery(2,[a,b,c,d,e,f,g,h],R).
R = [[a, b], [c, d], [e, f], [g, h]] ;
false.
?- splitEvery(4,[a,b,c,d,e,f,g,h],R).
R = [[a, b, c, d], [e, f, g, h]] ;
false.
?- splitEvery(8,[a,b,c,d,e,f,g,h],R).
R = [[a, b, c, d, e, f, g, h]] ;
false.
my code so far is this到目前为止我的代码是这样的
splitEvery(N,List,Res):-
splitEveryHelper1(N,List,Res,1,[]).
splitEveryHelper1(_,[],Acc,_,Acc).
splitEveryHelper1(N,[H|T],Res,C,[[H|HT]|AT]):-
C=<N,
C\_new is C+1,
splitEveryHelper1(N,T,Res,C_new,[[HT]|AT]).
splitEveryHelper1(N,List,Res,C,[AH|TR]):-
C>N,
C\_new=1,
splitEveryHelper1(N,List,Res,C_new,AT).
however it is not working properly但是它不能正常工作
This compact fragment satisfies the queries you listed此紧凑片段满足您列出的查询
splitEvery(N,L,R) :-
length(R,_),
maplist({N}/[X]>>length(X,N),R),
append(R,L).
but it has a big flaw (apart requiring library( yall )).但它有一个很大的缺陷(除了需要库( yall ))。 Can you spot it?你能发现吗?
Edit编辑
About your code: you're doing it more complex than required, and ignoring the messages the compiler gives you about singletons.关于你的代码:你做的比要求的更复杂,忽略编译器给你的关于单例的消息。
Remember that accumulators reverse the list, so you should remove them.请记住,累加器会反转列表,因此您应该删除它们。 Build instead the list in the output argument.而是在 output 参数中构建列表。
To give you a start:给你一个开始:
splitEvery(N,List,Res):-
splitEveryHelper1(N,List,1,Res).
splitEveryHelper1(_,[],_,[]).
splitEveryHelper1(N,[H|T],C,[[H|R]|AT]):-
C=<N,
C_new is C+1,
....
splitEveryHelper1(N,List,C,[[]|TR]):-
C>N,
C_new=1,
....
fill the dots with the proper recursive calls.用适当的递归调用填充点。 Then it will be working properly.然后它将正常工作。
It helps to decompose your problem.它有助于分解您的问题。 You want to take a list of things and split it up into a individual sublists of N items, correct?您想获取一个事物列表并将其拆分为 N 个项目的单个子列表,对吗?
That is a matter of repeatedly doing the following:这是反复执行以下操作的问题:
So, you need a predicated to pull no more than N items from the front of the list.因此,您需要一个谓词从列表的前面提取不超过 N 个项目。 There's 3 cases:有3种情况:
The general case: N > 0 and the list is non-empty.一般情况:N > 0 且列表非空。 Here, we add the head of the list to the prefix that we're building, decrement N, and recurse down on what's left.在这里,我们将列表的头部添加到我们正在构建的前缀中,递减 N,然后向下递归剩下的内容。
Special case #1: N > 0 and the list is empty.特殊情况 #1:N > 0 并且列表为空。 Here, we close the prefix and return the empty list as the suffix.在这里,我们关闭前缀并返回空列表作为后缀。
Special case #2: N is 0. Here, We close the prefix and return the source list as the suffix.特殊情况 #2:N 为 0。在这里,我们关闭前缀并将源列表作为后缀返回。
first( N , [X|L] , [X|Xs] , Sfx ) :- N > 0 , N1 is N-1 , first( N1, L, Xs, Sfx ) .
first( N , [] , [] , [] ) :- N > 0 .
first( 0 , Xs , [] , Xs ) .
Once we have that, it's an even easier matter of repeatedly invoking first/4
.一旦我们有了它,重复调用first/4
就更容易了。
split_every( _ , [] , [] ) .
split_every( N , [X|Xs] , [Pfx|LoL] ) :- first(N,[X|Xs],Pfx,Sfx), split_every(N,Sfx,LoL) .
You can, err... fiddle with it in this fiddle: https://swish.swi-prolog.org/p/split-list.pl你可以,错误......在这个小提琴中摆弄它: https://swish.swi-prolog.org/p/split-list.pl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.