我想将一个列表分成2个列表,如果数字小于P它进入L1,如果它大于P,那么它将进入L2。
这是我到目前为止,我能够以这种形式将列表L拆分为L1 = [[],[]]。但我想将列表拆分为2个列表L1和L2,我该怎么做?
split(L,P,L1):-
split(L,P,[],L1).
split([],_,[],[]).
split([],_,X,[X]) :- X \= [].
split([P|T],P,[],L1) :- split(T,P,[],L1).
split([P|T],P,L,[L|L1]) :- L \= [], split(T,P,[],L1).
split([H|T],P,S,L1) :- H \= P, append(S, [H], S2), split(T,P,S2,L1).
答案 0 :(得分:3)
您只需要三个规则来实现此谓词:
:- use_module(library(clpfd)).
split([], _, [], []).
split([H|T], P, L1, [H|T2]) :-
H #>= P,
split(T, P, L1, T2).
split([H|T], P, [H|T1], L2) :-
H #< P,
split(T, P, T1, L2).
代码非常简单
请注意,由于library(clpfd)
,此谓词也适用于当初始列表和枢轴未知时:
?- split(L,P,[5,47],[101]).
L = [101, 5, 47],
P in 48..101 ;
L = [5, 101, 47],
P in 48..101 ;
L = [5, 47, 101],
P in 48..101 ;
false.
partition/4
正如评论中提到的,您可以使用partition/4
执行此操作:
split(L, P, L1, L2) :-
partition(zcompare(>,P), L, L1, L2).
但是,这不会表现出与第一次实施一样多的不同行为。