如何将Prolog中的列表拆分为包含3个项目的多个列表?

时间:2012-04-06 08:34:40

标签: list split prolog items

我的问题是,我想制定一个规则,将列表拆分为多个列表,按顺序只包含原始列表中的3个项目。

例如:

/*original list:*/ 
Fruits=[apple,banana,orange,pear, lemon, melon]

?-Split(Fruits).

/*results:*/ 
[apple,banana,orange];
[banana,orange,pear];
[orange,pear,lemon];
[pear,lemon,melon].

有没有办法做到这一点? :S

2 个答案:

答案 0 :(得分:3)

您可以参考之前提供的this excellent answer @false。

快速调整他的解决方案,你可以写:

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

split_3(List, Result) :-
    length(Result, 3),
    phrase((seq(_),seq(Result),seq(_)),List).

请注意,append/2可以实现相同的目标(或append/3再打一次):

split_3(List, Result) :-
    length(Result, 3),
    append([_, Result, _], List).

append/2并非真正用于此类操作。 DCG使用差异列表,效率更高。

答案 1 :(得分:3)

Prolog非常适合这项任务。只需观察可以使用append / 3 在各个方向:

 % append(+List,+List,-List)
 % append(-List,-List,+List)
 append([], X, X).
 append([X|Y], Z, [X|T]) :-
     append(Y, Z, T).

现在只需按如下方式定义split / 2即可。它会找到_1和_2,这样L = _1 ++ S ++ _2,其中++是列表连接:

 % split(+List,-Sublist)
 split(L, S) :-
     append(_, H, L),
     append(S, _, H).

在这里你解决了你的问题:

 ?- Fruits=[apple,banana,orange,pear,lemon,melon], Split=[_,_,_], split(Fruits,Split).
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [apple,banana,orange] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [banana,orange,pear] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [orange,pear,lemon] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [pear,lemon,melon] ;
 No

再见

最好的问候