我想删除list1中的元素,当它等于list2中的元素时。 查询和预期输出是:
filter( [[1,2,3],[1]] , [[1]] , X ).
X = [[1, 2, 3]] ;
filter( [[1,2,3],[1],[2,3,4],[2]] , [[1],[2]] , X ).
X = [[1, 2, 3],[2,3,4]] ;
我现在所做的是:
filter(_,[],_).
filter([A|B],[A|D],E):-
filter(B,D,E).
filter([A|B],[C|D],[A|E]):-
A\=C,
filter(B,D,E).
但似乎不对,并给出如下输出:
11 ?- filter([[1,2,3],[1]],[[1]],X).
X = [[1, 2, 3]|_G488] ;
有人可以帮忙吗?也许我接近成功。
答案 0 :(得分:0)
您的程序无法正常工作,因为您每次都会从第二个列表中删除一个元素。您的基本情况(第一个子句)也不应该是一个未实例化的变量(这就是输出中|_G488
的结果。
您必须迭代第一个列表,过滤第二个列表中找到的元素,但不删除第二个列表中的元素。
例如:
filter([], _, []).
filter([Item|L1], L2, L3):-
(member(Item, L2) -> L4=L3;L3=[Item|L4]),
filter(L1, L2, L4).
第一个clase是递归的基本情况。它声明空列表的输出将是一个空列表。 第二个子句检查是否在第二个列表中找到输入列表的第一项。如果找到它,那么它将不会被添加到结果列表中;否则它被添加。然后它以输入列表的其余部分递归调用自身。 但绝不会从第二个列表中删除元素。
答案 1 :(得分:-1)
嗯,懒惰的方式是使用内置版findall/3
和member/2
:
filter( Xs , Ys , Rs ) :-
findall( X , ( member(X,Xs), \+ member(X,Ys) ) , Rs ) .
表示查找所有X
,X
是列表Xs
和Xs is *not* a member of the list
Ys`的成员。
假设您的教师希望您提出自己的实现,您可能首先想要分解您的问题。你需要做两件事:
迭代列表,删除在另一个列表中找到的项目。
给定一个项目,确定它是否包含在另一个列表中。
这两个都很简单。要确定某个项目是否包含在列表中,您可以说:
contained_in( X , [X|Ys] ) :- % if we find the item in the list,
! . % - we succeed and eliminate any alternatives.
contained_in( X , [_|Ys] ) :- % otherwise, we discard the head of the list,
contained_in(X,Ys) . % - and keep looking by recursing down.
实际过滤也非常简单:
filter( [] , _ , [] ) . % once the source list is exhausted, we're done.
filter( [X|Xs] , Ys , [X|R] ) :- % otherwise...
\+ contained_in(X,Ys) , % - if the current list item is not contained in the list of items to be removed,
! , % - cut off alternatives,
filter( Xs , Ys , R ) . % - add the current item to the result list and recurse down.
. %
filter( [_|Xs] , Ys , R ) :- % if the current list item IS contained in the list of items to be removed,
filter(Xs , Ys , R ) % - discard it and recurse down.
. % Easy!
答案 2 :(得分:-1)
您的filter
只有subtract
可用于许多Prolog系统(我已经使用B-Prolog,SWI-Prolog和ECLiPSe测试过):
?- subtract( [[1,2,3],[1]] , [[1]] , X ).
X = [[1, 2, 3]].
?- subtract( [[1,2,3],[1],[2,3,4],[2]] , [[1],[2]] , X ).
X = [[1, 2, 3], [2, 3, 4]].
您可以查看SWI-Prolog或ECLiPSe的来源了解实施细节。