Prolog,拆分成两个列表

时间:2015-01-31 09:36:04

标签: prolog

我遇到了列表问题。我需要做的是将一个列表[1,-2,3,-4]拆分为两个列表[1,3][-2,-4]。我的代码如下所示:

lists([],_,_).
lists([X|Xs],Y,Z):- lists(Xs,Y,Z), X>0 -> append([X],Y,Y) ; append([X],Z,Z).

我正在

Y = [1|Y],
Z = [-2|Z].

我做错了什么?

5 个答案:

答案 0 :(得分:1)

只是为了变化,这也可以通过DCG来完成,这对于像这样的问题很容易阅读:

split([], []) --> [].
split([X|T], N) --> [X], { X >= 0 }, split(T, N).
split(P, [X|T]) --> [X], { X < 0 }, split(P, T).

split(L, A, B) :-
    phrase(split(A, B), L).

如:

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

A = [1,2,3]
B = [-4,-5] ? ;

no

它还提供了所有可能的解决方案:

| ?- split(L, [1,2,3], [-4,-5]).

L = [1,2,3,-4,-5] ? ;

L = [1,2,-4,3,-5] ? ;

L = [1,2,-4,-5,3] ? ;

L = [1,-4,2,3,-5] ? ;

L = [1,-4,2,-5,3] ? ;

L = [1,-4,-5,2,3] ? ;

L = [-4,1,2,3,-5] ? ;

L = [-4,1,2,-5,3] ? ;

L = [-4,1,-5,2,3] ? ;

L = [-4,-5,1,2,3] ? ;

(2 ms) no
如果删除剪切并在X < 0谓词的第三个子句中放置明确的split/3检查,Gaurav的解决方案也会执行此操作。

答案 1 :(得分:1)

如果您的Prolog系统提供,您可以保留。想知道怎么样? 继续阅读!

我们采用@CapelliC写的lists/3的第二个定义 his answer作为起点,并tpartition/4替换partition/4(#<)/3替换(<)/2

lists(A,B,C) :- tpartition(#<(0),A,B,C).

让我们运行一个示例查询!

?- As = [0,1,2,-2,3,4,-4,5,6,7,0], lists(As,Bs,Cs).
As = [0,1,2,-2,3,4,-4,5,6,7,0],
Bs = [  1,2,   3,4,   5,6,7  ],
Cs = [0,    -2,    -4,      0].

当我们使用单调代码时,我们会获得更一般的查询的逻辑上合理的答案:

?- As = [X,Y], lists(As,Bs,Cs).
As = [X,Y], Bs = [X,Y], Cs = [   ], X in   1..sup, Y in   1..sup ;
As = [X,Y], Bs = [X  ], Cs = [  Y], X in   1..sup, Y in inf..0   ;
As = [X,Y], Bs = [  Y], Cs = [X  ], X in inf..0  , Y in   1..sup ;
As = [X,Y], Bs = [   ], Cs = [X,Y], X in inf..0  , Y in inf..0   . 

答案 2 :(得分:0)

参考:

domains
    list=integer*

predicates
    split(list,list,list)
clauses
    split([],[],[]).
    split([X|L],[X|L1],L2):-
        X>= 0,
        !,    
        split(L,L1,L2).

    split([X|L],L1,[X|L2]):-
        split(L,L1,L2).
  

输出:

目标:分裂([1,2,-3,4,-5,2],X,Y)
解决方案: X = [1,2,4,2],Y = [ - 3,-5]

看,如果有帮助的话。

答案 3 :(得分:0)

您的代码中需要进行多项更正。 如果您喜欢紧凑(可读)代码,则有可能

lists([],[],[]).
lists([X|Xs],Y,Z) :-
  ( X>0 -> (Y,Z)=([X|Ys],Zs) ; (Y,Z)=(Ys,[X|Zs]) ), lists(Xs,Ys,Zs).

但是,因为(SWI)Prolog提供了处理常见列表处理任务的库,所以可以像

一样简单
lists(A,B,C) :- partition(<(0),A,B,C).

答案 4 :(得分:0)

你有。它会分割一个列表,如果有奇数或偶数项目无关紧要。

GET "/user/{id}/profile_picture/{profile picture relative url}"