Prolog - 返回包含特定元素的列表?

时间:2015-09-12 18:23:28

标签: list prolog

我正在努力学习Prolog,而且我一直在做一些练习。

有一个包含学生姓名的列表。编写谓词filter(L,LN),返回名为LN的第二个列表,其中包含如下名称:

?- filter([kostas, dimitris, anna, antonis, antonia], LN).
LN = [kostas, anna, antonia]

所以..它显示一个,然后跳过一个并持续这样做。 这就是我所做的,但这不正确。

filter([],[]).
filter([H|T],[H|LN]) :-
    filter(T,LN,0).

filter([H|T],[H|LN],C) :-
    0 is C mod 2, 
    append(H,LN),
    C = C + 1, 
    filter(T,LN,C). 
filter([H|T],LN,C) :-
    (C/2) \= 0,
    C = C + 1,
    filter(T,LN,C).

2 个答案:

答案 0 :(得分:4)

使用DCG的许多情况之一会让您的生活更轻松:

Runnable

如果没有DCG,这看起来像是:

s([]) --> [].
s([X|Xs]) --> [X], t(Xs).

t([]) --> [].
t(Xs) --> [_], s(Xs).

filter_dcg(List, Filtered) :-
    phrase(s(Filtered), List).

这里的回家消息是,您尝试实现的内容很容易实现为具有两种状态的状态机。它们中的每一个都转换到另一个,一个保持其输入,另一个抛弃它。

答案 1 :(得分:2)

这是一个不使用任何算术的简单答案:

filter([],[]).
filter([A],[A]).
filter([A,_|T],[A|T2]) :-
    filter(T,T2).

对于空列表,结果为空列表。 对于一个元素的列表,结果是该元素的列表。 对于两个或更多元素的列表,结果是第一个元素后跟前两个元素之后的元素过滤结果(所以我们丢弃第二个元素)。