在prolog中拆分列表,生成两个单独的列表

时间:2015-06-01 14:03:51

标签: list prolog

问题:

  

定义谓词split / 4,当提供列表L和整数N时,返回两个列表A和B,其中A包含L中大于或等于N的项,B包含项低于N.

具有预期结果的示例查询:

var co = require('co');

co(function* () {
  yield waitAndDo(10);
});

我的代码:

?- split([1, 5, 2, 3, 4], 3, A, B).
A = [5, 3, 4],
B = [1, 2].

我的代码只返回spit([], 0, [], []). split([I|Is], N, [A|As], [_B|Bs]):- I >= N, A is I, split(Is, N, As, Bs). split([I|Is], N, [_A|As], [B|Bs]):- I < N, B is I, split(Is, N, As, Bs). ,而不是根据需要生成AB。我不确定为什么。

3 个答案:

答案 0 :(得分:3)

接近纠正,但有些小错误。

逐行:

A)

spit([], 0, [], []).

错字:spi vs split

规则说“将空列表拆分为0是两个空列表”,为真,但限制性太强,将其更改为“空列表的拆分是两个空列表,无论数字”:

split([], _, [], []).

b)中

split([I|Is], N, [A|As], [_B|Bs]):-
    I >= N,
    A is I,
    split(Is, N, As, Bs).

“B”仍未定义,即使您将其作为_B来启动警告也是如此。将其更改为:

split([I|Is], N, [I|As], Bs ):-
    I >= N,
    split(Is, N, As, Bs).

c)中

split([I|Is], N, [_A|As], [B|Bs]):-
    I < N,
    B is I,
    split(Is, N, As, Bs).

与之前相同。

答案 1 :(得分:2)

作为partition/4的替代方案,请使用 tpartition/4(#=<)/3一起使用,如下所示:

?- tpartition(#=<(3),[1,5,2,3,4],As,Bs).
As = [5,3,4], Bs = [1,2].

感谢(#=<)/3,您可以运行更常见的查询!

有关详细信息,请查看my answer相关问题 “Splitting a list of integers into a list of positive integers and a list of negative integers”。

答案 2 :(得分:1)

我认为这是家庭作业,因为使用SWI-Prolog,你有分区/ 4

  

分区(:Pred,+ List,?包含,?排除)[det]

     
    

根据Pred。过滤List的元素     如果Included包含调用的所有元素,则为True(Pred,X)     成功,排除包含剩余的元素。

  
split(L, N, A, B) :-
    partition( =<(N), L, A, B).