我的问题是,我想制定一个规则,将列表拆分为多个列表,按顺序只包含原始列表中的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
答案 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
再见
最好的问候