我在删除prolog列表中的值时遇到了一些麻烦。 我有一个颜色列表,我想添加一个颜色列表,并保留所有没有重复的值,并删除其余的。
[green, red, blue, purple, yellow, brown, orange, black, purple]
所以紫色在这个列表中出现两次,我想删除它们。 这是我想要返回的列表。
[green, red, blue, yellow, brown, orange, black]
我目前有这个删除所有重复项,但我不能得到两个purples。
mymember(X,[H|_]) :- X==H,!.
mymember(X,[_|T]) :- mymember(X,T).
not(A) :- \+ call(A).
set([],[]).
set([Head|Tail],[Head|Out]) :-
not(mymember(Head,Tail)),
set(Tail, Out).
set([Head|Tail],Out) :-
mymember(Head,Tail),
set(Tail, Out).
这是我现在得到的结果:
[green, red, blue, yellow, brown, orange, black, purple]
答案 0 :(得分:3)
简单的方法......单行:
singletons(Xs,Zs) :-
findall( X , ( append(P,[X|S],Xs), \+member(X,P), \+member(X,S) ) , Zs )
.
答案 1 :(得分:3)
将 pure 与tfilter/3
结合使用,保持list_uniqmember_t/3
!
list_uniqs(Es, Us) :-
tfilter(list_uniqmember_t(Es), Es, Us).
OP给出的样本查询具有预期结果:
?- list_uniqs([green,red,blue,purple,yellow,brown,orange,black,purple], Xs).
Xs = [green,red,blue,yellow,brown,orange,black]. % succeeds deterministically
对于更一般的查询,我们是否也获得了逻辑上合理的答案?
?- list_uniqs([A,B,A], []). A=B ; false. ?- list_uniqs([A,B,A], [_]). dif(A,B). ?- list_uniqs([A,B,A], [_,_]). false. ?- list_uniqs([A,B,A], Xs). Xs = [] , A=B ; Xs = [B], dif(A,B).
是的! 一点更通用的东西怎么样?
?- list_uniqs([A,B,C],Xs). Xs = [] , A=B , B=C ; Xs = [C] , A=B , dif(B,C) ; Xs = [B] , A=C , dif(B,C) ; Xs = [A] , dif(A,C), B=C ; Xs = [A,B,C], dif(A,B), dif(A,C), dif(B,C).
有效!
答案 2 :(得分:1)
我认为你走在正确的轨道上。这是一种使用 - >的方法。 ;构造并利用delete / 3谓词,删除所有重复项:
remdup([], _, []).
remdup([H|T], X, R) :-
( H == X
-> ( member(X, T)
-> delete(T, X, R) % only delete if it's in the list more than once
; R = [H|R1],
remdup(T, X, R1)
)
; R = [H|R1],
remdup(T, X, R1)
).
另一种解决方案,使用select/3
以及delete/3
:
remdup(L, X, R) :-
(select(X, L, L1), select(X, L1, L2))
-> delete(L2, X, R)
; L = R.
select/3
从列表中提取元素的一个实例。如果找不到元素,则失败。所以在上面,如果我们能够找到至少两个实例,我们会删除所有实例。
remdup([], []).
remdup([H|T], R) :-
( select(H, T, T1)
-> delete(T1, H, R1),
remdup(R1, R)
; R = [H|R1],
remdup(T, R1)
).
答案 3 :(得分:0)
我通过这样做来修复它:
my_delete(Res, [], Res).
my_delete(Colorslist, [Head|Tail], R) :-
my_delete_worker(Colorslist, Head, Result),
my_delete(Result, Tail, R).
my_delete_worker([], _, []).
my_delete_worker([X|T], X, R) :-
my_delete_worker(T, X, R).
my_delete_worker([H|T], X, [H|R]) :-
X \= H,
my_delete_worker(T, X, R).
我忘记将第一种颜色的结果放入第二种颜色的颜色列表中。当它到达基本情况时,我将结果与我的色彩列表统一起来。 谢谢你的帮助潜伏者!
答案 4 :(得分:0)
更简单(和不纯: - )
singletons(Xs, Zs) :- findall(X, (select(X,Xs,Ys), \+memberchk(X,Ys)), Zs).