您好我必须解决一些列表的prolog问题,但我无法弄清楚这些是如何工作的。 我必须在列表中的每个偶数元素后面添加“1”,以区分2个列表。 我知道这看起来很容易,在其他语言如java或c#中我会很容易,但是prolog它让我很头疼。 请帮帮我:|
答案 0 :(得分:1)
编辑注意澄清的问题陈述("偶数项"意味着项目的值是偶数(而不是列表中项目的序号位置):
insert_one_after_even_items( [] , [] ). % if the source list is exhaused, we're done.
insert_one_after_even_items( [X|Xs] , [X,1|Ys] ) :- % otherwise,
0 is X mod 2 , % - if the number is even, prepend it and a 1 to the result list, and
insert_one_after_even_items( Xs , Ys ) % - recurse down.
. %
insert_one_after_even_items( [X|Xs] , [X|Ys] ) :- % otherwise,
1 is X mod 2 , % - if the number is odd, prepend it to the result list, and
insert_one_after_even_items( Xs , Ys ) % - recurse down.
. % Easy!
对于你的第二个问题,产生两个列表之间的差异,你在谈论集合差异吗?如果是这样,给定两组A和B,你是在谈论相对差异(B中不存在的A的所有元素),还是绝对差异(两个集合中不存在的A或B的所有元素) ?
要解决相对集差异问题(查找B中不存在的A的所有成员),您可以使用内置的member/2
谓词:
relative_difference( [] , _ , [] ) . % if the source list is exhausted, we're done
relative_difference( [A|As] , Bs , R ) :- % if the source list is non-empty, and
member(A,Bs) , % - the current A is an element of B,
! , % - we insert a deterministic cut (no backtracking)
relative_difference( As , Bs , R ) % - and recurse down, discarding the current A
. %
relative_difference( [A|As] , Bs , [A|R] ) :- % if the source list is non-empty (and A is not an element of B due to the cut inserted earlier)
relative_difference( As , Bs , R ) % we simply add A to the result list and recurse down.
.
您将在此处注意一件事:我们正在构建结果列表,所有这些示例都是从变量构建的。列表的尾部是未绑定的(并作为新结果传递给下一个递归调用,它将成为新的列表节点,或者最后是空列表。
这具有
的效果如果你的prolog实现没有member/2
作为内置,那么它很容易实现。像这样的东西应该这样做:
member(X,[X|T]) :- ! . % A hit! cut and succeed.
member(X,[_|T]) :- member(X,T) . % ... and a miss. Just recurse down on the tail.