我编写了一些代码来删除列表中的所有重复项,以便remove_duplicates([1,2,3,4,5,3,4,5], L).
获取L = [1, 2, 3, 4, 5].
member1(X,[H|_]) :-
X==H,!.
member1(X,[_|T]) :-
member1(X,T).
remove_duplicates([],[]).
remove_duplicates([H|T],X) :-
member1(H,T),
!,
remove_duplicates(T,X).
remove_duplicates([H|T],[H|X]) :-
remove_duplicates(T,X).
我想要做的是删除副本并删除原件,以便remove_duplicates([1,2,3,4,5,3,4,5], L).
获取L = [1, 2].
,其中3,4和5将被移除。
答案 0 :(得分:1)
这是remove_duplicates的一种方法,但它不是尾递归的。
remove_duplicates([],[]).
remove_duplicates([H|T], X) :-
remove_duplicates(T,X1),
( member(H, X1)
-> select(H, X1, X)
; X = [H |X1]).
是的,我的第一个代码不正确,因为我没有记住重复。这是一个正确的解决方案:
remove_duplicates(In, Out) :-
remove_duplicates(In, _, Out).
remove_duplicates([],[], []).
remove_duplicates([H|T], Dup, X) :-
remove_duplicates(T,Dup1, X1),
( member(H, Dup1)
-> X = X1,
Dup = Dup1
; ( member(H, X1)
-> select(H, X1, X),
Dup = [H | Dup1]
; X = [H | X1],
Dup = Dup1)).
我们得到了
?- remove_duplicates([1,2,3,2,1,2,3,4,5], L).
L = [4, 5] ;
false.
答案 1 :(得分:0)
而不是member1 / 2,你可以使用select / 3,所以元素被删除,然后涓流其余的参数:
remove_duplicates([],[]).
remove_duplicates([H|T],X) :-
select(H,T,R),
!,
remove_duplicates([H|R],[H|X]).
remove_duplicates([H|T],[H|X]) :-
remove_duplicates(T,X).
编辑事实证明,代码是错误的,例如,在?- remove_duplicates([2,2,2],X).
上失败了:这里是一个修正
remove_duplicates([],[]).
remove_duplicates([H|T],X) :-
select(H,T,R),
!, findall(X, (member(X, R), X\=H), NotH),
remove_duplicates(NotH, X).
remove_duplicates([H|T],[H|X]) :-
remove_duplicates(T,X).
答案 2 :(得分:0)
我有这个:
remove_duplicates(List, NewList):-
once(remove_duplicates(List,[],[],NewList)).
remove_duplicates([],_ACALL,Ac,Ac).
remove_duplicates(List,ACALL,Ac,NewList):-
List= [H|T],
member(H,ACALL),
select(H,Ac,NewAc),
remove_duplicates(T,ACALL,NewAc,NewList).
remove_duplicates(List,ACALL,Ac,NewList):-
List= [H|T],
member(H,ACALL),
remove_duplicates(T,ACALL,Ac,NewList).
remove_duplicates(List,ACALL, Ac,NewList):-
List =[H|T],
not(member(H,ACALL)),
remove_duplicates(T,[H|ACALL],[H|Ac],NewList).
我使用两个累加器,一个用于记录所有看到的项目(ACALL),另一个用于返回当前列表..这是一个很好的方法吗?