Prolog,将列表分成两个列表
Prolog, split list into two lists
列表有问题。我需要做的是将一个列表 [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].
我做错了什么?
参考这个:
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).
Output :
目标: split([1,2,-3,4,-5,2],X,Y)
解法: X=[1,2,4,2], Y=[-3,-5]
看看有没有帮助。
只是为了多样化,这也可以用 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
Gaurav 的解决方案也将执行此操作,如果剪切被删除并且显式 X < 0
检查置于 split/3
谓词的第三个子句中。
您的代码中有几处需要更正。
如果您喜欢紧凑(可读)代码,一种可能性是
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).
如果您的 Prolog 系统提供 clpfd you could preserve logical-purity。想知道怎么做吗? 继续阅读!
我们取@CapelliC写的lists/3
的第二个定义
as a starting point, and replace partition/4
by tpartition/4
and (<)/2
by (#<)/3
:
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 .
给你。它拆分一个列表,无论项目数是奇数还是偶数都没有关系。
div(L, A, B) :-
append(A, B, L),
length(A, N),
length(B, N).
div(L, A, B) :-
append(A, B, L),
length(A, N),
N1 is N + 1,
length(B, N1).
div(L, A, B) :-
append(A, B, L),
length(A, N),
N1 is N - 1,
length(B, N1).
列表有问题。我需要做的是将一个列表 [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].
我做错了什么?
参考这个:
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).
Output :
目标: split([1,2,-3,4,-5,2],X,Y)
解法: X=[1,2,4,2], Y=[-3,-5]
看看有没有帮助。
只是为了多样化,这也可以用 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
Gaurav 的解决方案也将执行此操作,如果剪切被删除并且显式 X < 0
检查置于 split/3
谓词的第三个子句中。
您的代码中有几处需要更正。 如果您喜欢紧凑(可读)代码,一种可能性是
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).
如果您的 Prolog 系统提供 clpfd you could preserve logical-purity。想知道怎么做吗? 继续阅读!
我们取@CapelliC写的lists/3
的第二个定义
partition/4
by tpartition/4
and (<)/2
by (#<)/3
:
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 .
给你。它拆分一个列表,无论项目数是奇数还是偶数都没有关系。
div(L, A, B) :-
append(A, B, L),
length(A, N),
length(B, N).
div(L, A, B) :-
append(A, B, L),
length(A, N),
N1 is N + 1,
length(B, N1).
div(L, A, B) :-
append(A, B, L),
length(A, N),
N1 is N - 1,
length(B, N1).