2012-04-06 76 views
4

我的問題是,我想制定一個規則,將列表拆分爲多個列表,其中只包含原始列表中的3個項目。如何將Prolog中的列表分成幾個包含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,結果應該是什麼?你有什麼版本的Prolog? – 2012-04-06 08:35:58

+0

它應該是False/No。 我有SWI 5.10.5 – 2012-04-06 08:55:32

回答

3

序言非常適合這項任務。只觀察/ 3可在各種方向上使用 該追加:

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

現在簡單地定義分裂/ 2如下。它會找到_1和_2,使得L = _1 ++小號++ _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 

再見

最好的問候

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使用差異列表,效率更高。

+0

很好,非常感謝你,完美的作品:D – 2012-04-06 10:02:14

+1

如果你對Prolog感興趣,花點時間理解正確的答案,我將鏈接的時間花在btw上! – m09 2012-04-06 10:07:09

相關問題