我正在努力学习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).
答案 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).
对于空列表,结果为空列表。 对于一个元素的列表,结果是该元素的列表。 对于两个或更多元素的列表,结果是第一个元素后跟前两个元素之后的元素过滤结果(所以我们丢弃第二个元素)。