如何在Prolog中将一个列表拆分成包含3个元素的多个列表?

3

我的问题是,我想要一个规则来将一个列表分成几个列表,每个列表都包含原始列表中按顺序的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

如果列表的长度小于3,应该得到什么结果?你使用的Prolog版本是什么? - Chetter Hummin
应该是False/否。我有SWI 5.10.5。 - Peter Ivanics
2个回答

3
你可以参考 @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
如果你对Prolog感兴趣,花时间正确理解我链接的答案中发生的事情是值得的! - m09

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

你好

最好的问候


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接