我想订购自定义列表。我想订购的清单将采用这种形式......
[n(_,2,_),n(_,1,_),n(_,3,_)]
我写了一个比较器
cheaper(n(_,C1,_),n(_,C2,_)) :-
C1>C2.
如何在predsort中使用它。我使用冒泡排序编写了一个排序算法,但是我有非常大的列表,所以它非常慢。
可以吗
predsort(cheaper, [n(_,2,_),n(_,1,_),n(_,3,_)] , X).
谢谢:)
答案 0 :(得分:5)
试试这个:
cheaper(>, n(_,C1,_),n(_,C2,_)) :-
C1>C2.
cheaper(<, n(_,C1,_),n(_,C2,_)) :-
C1<C2.
cheaper(=, n(_,C1,_),n(_,C2,_)) :-
C1=C2.
请注意,predsort就像排序一样,没有双打!如果你想保持双打,试试
cheaper(>, n(_,C1,_),n(_,C2,_)) :-
C1>C2.
cheaper(<, n(_,C1,_),n(_,C2,_)) :-
C1=<C2.
答案 1 :(得分:4)
Joel已经展示了基本情况(+1),但为了获得更好的性能,请避免重复测试:
cheaper(R, n(_,C1,_),n(_,C2,_)) :-
C1>C2 -> R = > ; R = < .
修改的
现在SWI-Prolog有另一个内置sort / 4,对于简单的情况,它可以避免与用户定义的谓词调用相关的惩罚:
?- sort(2,@=<,[n(_,2,_),n(_,1,_),n(_,3,_)],S).
S = [n(_2578, 1, _2582), n(_2564, 2, _2568), n(_2592, 3, _2596)].
答案 2 :(得分:2)
尽量避免使用predsort/3
。这是一个SWI特定的谓词,它不是特别有效,因为所有~O(n log n)比较都是通过调用你的定义来执行的。而是尝试使用keysort/2
这是一个标准谓词,并且不会产生任何此类调用开销:
首先将列表Ns
映射到对KNs
对列表,然后排序,然后提取值。
n_pricep(N, C-N) :-
N = n(_,C,_).
pair_value(_-V,V).
...,
maplist(n_pricep, Ns, KNs),
keysort(KNs, KNsS),
maplist(pair_value, KNsS, NsS).