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

4

2 回答 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 使用差异列表,效率更高。

于 2012-04-06T09:23:33.903 回答
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

再见

最好的祝福

于 2012-04-06T11:40:52.070 回答