这与我的上一个问题相似,但我现在想用字母过滤一个列表。
test_filter0 :- filter_list([a,b,c,a,b,c],a,[a,a]).
test_filter1 :- filter_list([abc,abc,abc,bc,bc,bc,cd],bc,[bc,bc,bc]).
test_filter2 :- filter_list([a,b,c,d,e,f,g],h,[]).
test_filter3 :- filter_list([a,b,b,b,c,b,b],b,[b,b,b,b,b]).
test_filter :- test_filter0, test_filter1, test_filter2, test_filter3.
我试过了:
filter_list([],C,[]) :- true, !.
filter_list([A|L1],C,[A|L2]) :- A==C, filter_list(L1,C,L2).
filter_list([A|L1],C,L2) :- C==A, filter_list(L1,C,L2).
答案 0 :(得分:-1)
非常接近,您只需要在filter_list/3
的最后一个条款中使用不等式,如下所示:
filter_list([], C, []).
filter_list([A|L1], C, [A|L2]) :-
A == C, % equal to
filter_list(L1, C, L2).
filter_list([A|L1], C, L2) :-
C \== A, % not equal to
filter_list(L1, C, L2).
为了提高效率,可以在!
之后添加一个剪切(A == C
)来提交到该分支,因为每当调用第二个子句时,Prolog都会留下一个执行最后一个子句的选择点,因为最后一个具有包含前者([A|L1], C, L2
)的绑定模式(即[A|L1], C, [A|L2]
)。请注意,第一个子句实际上并不需要剪切,因为[], C, []
的绑定模式不包含在谓词的任何其他后续子句的绑定模式中。