Prolog 从列表的所有重复元素中选择最小值
举个例子可以更好地解释我想做的事情。 例如,我有一个序言列表:Prolog 从列表的所有重复元素中选择最小值,prolog,Prolog,举个例子可以更好地解释我想做的事情。 例如,我有一个序言列表: L=[(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)] 我想生成以下列表: L'=[(d,15),(g,23),(e,14),(h,23)] 也就是说,从元素(X,u)的所有出现中,保留Y最小的元素。不是很优雅,而是。。。下面的代码呢 getFirst((X, _), X). isMinor(_, []). isMinor((X1, Y1), [(X2, _) | T]) :- X1
L=[(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)]
我想生成以下列表:
L'=[(d,15),(g,23),(e,14),(h,23)]
也就是说,从元素(X,u)的所有出现中,保留Y最小的元素。不是很优雅,而是。。。下面的代码呢
getFirst((X, _), X).
isMinor(_, []).
isMinor((X1, Y1), [(X2, _) | T]) :-
X1 \= X2,
isMinor((X1, Y1), T).
isMinor((X, Y1), [(X, Y2) | T]) :-
Y1 =< Y2,
isMinor((X, Y1), T).
purgeList(_, [], []).
purgeList(X1, [(X2, Y2) | Tin], [(X2, Y2) | Tout]) :-
X1 \= X2,
purgeList(X1, Tin, Tout).
purgeList(X, [(X, _) | Tin], Tout) :-
purgeList(X, Tin, Tout).
filterList([], []).
filterList([H1 | Tin1], [H1 | Tout]) :-
isMinor(H1, Tin1),
getFirst(H1, X),
purgeList(X, Tin1, Tin2),
filterList(Tin2, Tout).
filterList([H1 | Tin], Tout) :-
\+ isMinor(H1, Tin),
filterList(Tin, Tout).
我获得(L
与统一)
你也可以写:
select_elements(L,Lout):-
sort(L,L1),
reverse(L1,L2),
remove(L2,L3),
output_list(L,L3,Lout).
remove([],[]).
remove([H],[H]).
remove([(X,Y1),(X,Y2)|T],[(X,Y1)|T1]):-remove([(X,Y2)|T],T1).
remove([(X1,Y1),(X2,Y2)|T],[(X1,Y1)|T1]):-
dif(X1,X2),\+member((X2,_),T),
remove([(X2,Y2)|T],T1).
remove([(X1,Y1),(X2,_)|T],[(X1,Y1)|T1]):-
dif(X1,X2),member((X2,_),T),
remove(T,T1).
output_list([],_,[]).
output_list([H|T],L,[H|T1]):-member(H,L),output_list(T,L,T1).
output_list([H|T],L,T1):- \+member(H,L),output_list(T,L,T1).
例如:
?- select_elements([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)],L).
L = [ (d, 15), (g, 23), (e, 14), (h, 23)] ;
false.
你可以试试
test((V, N), Y, Z) :-
( member((V,N1), Y)
-> ( N < N1
-> select((V,N1), Y, (V,N), Z)
; Z = Y)
; append(Y, [(V,N)], Z)).
my_select(In, Out) :-
foldl(test, In, [], Out).
不是很优雅,但这正是我想要的,而且很有效。谢谢
?- select_elements([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)],L).
L = [ (d, 15), (g, 23), (e, 14), (h, 23)] ;
false.
test((V, N), Y, Z) :-
( member((V,N1), Y)
-> ( N < N1
-> select((V,N1), Y, (V,N), Z)
; Z = Y)
; append(Y, [(V,N)], Z)).
my_select(In, Out) :-
foldl(test, In, [], Out).
?- my_select([(d,15),(e,16),(g,23),(e,14),(h,23),(d,19)], Out).
Out = [(d,15),(e,14),(g,23),(h,23)] ;
false.