过滤列表序言

时间:2010-12-07 03:45:22

标签: prolog

这与我的上一个问题相似,但我现在想用字母过滤一个列表。

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).

1 个答案:

答案 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, []的绑定模式不包含在谓词的任何其他后续子句的绑定模式中。