【问题标题】:How can I split a list in Prolog to several lists containing 3 items?如何将 Prolog 中的列表拆分为包含 3 个项目的多个列表?
【发布时间】:2012-04-06 08:34:39
【问题描述】:

我的问题是,我想制定一个规则,将一个列表拆分为多个列表,按顺序仅包含原始列表中的 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?
  • 应该是False/No。我有 SWI 5.10.5

标签: list split prolog items


【解决方案1】:

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

再见

最好的问候

【讨论】:

    【解决方案2】:

    您可以参考前段时间提供的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 使用差异列表,效率更高。

    【讨论】:

    • 如果您对 Prolog 感兴趣,那么花时间正确理解我链接的答案中发生的事情是值得的时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    相关资源
    最近更新 更多