簡體   English   中英

一個 prolog 謂詞,用於將列表拆分為每 n 個元素的單獨列表

[英]A prolog predicate to split a list into sperate lists ever n elements

標題是必需的謂詞,這里有幾個示例查詢

?- 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.

到目前為止我的代碼是這樣的

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

但是它不能正常工作

此緊湊片段滿足您列出的查詢

splitEvery(N,L,R) :-
    length(R,_),
    maplist({N}/[X]>>length(X,N),R),
    append(R,L).

但它有一個很大的缺陷(除了需要庫( yall ))。 你能發現嗎?

編輯

關於你的代碼:你做的比要求的更復雜,忽略編譯器給你的關於單例的消息。

請記住,累加器會反轉列表,因此您應該刪除它們。 而是在 output 參數中構建列表。

給你一個開始:

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,
    ....

用適當的遞歸調用填充點。 然后它將正常工作。

它有助於分解您的問題。 您想獲取一個事物列表並將其拆分為 N 個項目的單個子列表,對嗎?

這是反復執行以下操作的問題:

  • 從列表的頂部拉出不超過 N 個項目,並且
  • 遞歸到剩下的東西。

因此,您需要一個謂詞從列表的前面提取不超過 N 個項目。 有3種情況:

  • 一般情況:N > 0 且列表非空。 在這里,我們將列表的頭部添加到我們正在構建的前綴中,遞減 N,然后向下遞歸剩下的內容。

  • 特殊情況 #1:N > 0 並且列表為空。 在這里,我們關閉前綴並返回空列表作為后綴。

  • 特殊情況 #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  ) .

一旦我們有了它,重復調用first/4就更容易了。

  • 如果源列表為空,則列表列表為空。
  • 如果源列表非空,我們
    • 從源列表中提取前 N 個項目,並且
    • 遞歸到剩下的任何東西
split_every( _ , []     , []        ) .
split_every( N , [X|Xs] , [Pfx|LoL] ) :- first(N,[X|Xs],Pfx,Sfx), split_every(N,Sfx,LoL) .

你可以,錯誤......在這個小提琴中擺弄它: https://swish.swi-prolog.org/p/split-list.pl

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM