如何在 Swi-Prolog 中排序元组列表
How to order a list of tuples in Swi-Prolog
我在 swi-prolog 中有一个这样的列表:
[(5,4), (1,4), (3,12), (4,2), (5,4)]
我需要按照每个 "tuple" 的第二个元素来组织列表,删除任何重复的元素,所以这个列表看起来像这样:
[(4,2), (1,4), (5,4), (3,12)]
使用谓词 sort/2,它做我想要的一切,除了它根据每个元组的第一个元素组织,这是我不想要的。
我该怎么做?
受到 http://kti.mff.cuni.cz/~bartak/prolog/sorting.html 的启发,我修改了枢轴算法以满足您的需求。我在 Sicstus Prolog 上测试过并且它有效。
:- use_module(library(lists)).
pivoting(_,[],[],[]).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D>B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D=B,C>A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D<B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D=B,C<A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,G):-A=C,D=B,pivoting((A,B),T,L,G).
quick_sort(List,Sorted):-q_sort(List,[],Sorted).
q_sort([],Acc,Acc).
q_sort([H|T],Acc,Sorted):-
pivoting(H,T,L1,L2),
q_sort(L1,Acc,Sorted1),q_sort(L2,[H|Sorted1],Sorted).
如果您不想编写自己的排序例程(您的 Prolog 的排序可能比您的更优化),可能有特定于实现的谓词,您可以使用您选择的比较。
例如,SWI-Prolog 有 predsort/3
,它接受一个谓词作为排序依据。您可以将它与首先比较一对中的第二个元素的谓词一起使用:
compare_by_second(<, (A, B), (C, D)) :-
( B @< D
; B == D,
A @< C ).
compare_by_second(=, (A, B), (C, D)) :-
A == C,
B == D.
compare_by_second(>, (A, B), (C, D)) :-
( B @> D
; B == D,
A @> C ).
% ?- predsort(compare_by_second, [(5,4), (1,4), (3,12), (4,2), (5,4)], Sorted).
%@ Sorted = [ (4, 2), (1, 4), (5, 4), (3, 12)] ;
%@ false.
我在 swi-prolog 中有一个这样的列表:
[(5,4), (1,4), (3,12), (4,2), (5,4)]
我需要按照每个 "tuple" 的第二个元素来组织列表,删除任何重复的元素,所以这个列表看起来像这样:
[(4,2), (1,4), (5,4), (3,12)]
使用谓词 sort/2,它做我想要的一切,除了它根据每个元组的第一个元素组织,这是我不想要的。
我该怎么做?
受到 http://kti.mff.cuni.cz/~bartak/prolog/sorting.html 的启发,我修改了枢轴算法以满足您的需求。我在 Sicstus Prolog 上测试过并且它有效。
:- use_module(library(lists)).
pivoting(_,[],[],[]).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D>B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],[(C,D)|L],G):-D=B,C>A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D<B,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,[(C,D)|G]):-D=B,C<A,pivoting((A,B),T,L,G).
pivoting((A,B),[(C,D)|T],L,G):-A=C,D=B,pivoting((A,B),T,L,G).
quick_sort(List,Sorted):-q_sort(List,[],Sorted).
q_sort([],Acc,Acc).
q_sort([H|T],Acc,Sorted):-
pivoting(H,T,L1,L2),
q_sort(L1,Acc,Sorted1),q_sort(L2,[H|Sorted1],Sorted).
如果您不想编写自己的排序例程(您的 Prolog 的排序可能比您的更优化),可能有特定于实现的谓词,您可以使用您选择的比较。
例如,SWI-Prolog 有 predsort/3
,它接受一个谓词作为排序依据。您可以将它与首先比较一对中的第二个元素的谓词一起使用:
compare_by_second(<, (A, B), (C, D)) :-
( B @< D
; B == D,
A @< C ).
compare_by_second(=, (A, B), (C, D)) :-
A == C,
B == D.
compare_by_second(>, (A, B), (C, D)) :-
( B @> D
; B == D,
A @> C ).
% ?- predsort(compare_by_second, [(5,4), (1,4), (3,12), (4,2), (5,4)], Sorted).
%@ Sorted = [ (4, 2), (1, 4), (5, 4), (3, 12)] ;
%@ false.