按照 generate & test 方法,您可以编写:
median(List,Median) :-
dif(List,[]), msort(List,SList), length(List,Len),
append(Low,[Median],Tmp), append(Tmp,High,SList),
length(Low,LowLen), div(Len,2)=:=LowLen, !.
这有一个方便的声明式阅读:Median 是一个非空的List 的值,它将List 的排序版本SList 分成两半Low 和High,即。 Median 是List 中值分布的“中间元素”。
确实,上面的程序通过检查SList是否可以写成列表连接Low + [Median] + High来确定Median,使得Low的长度是SList长度的一半。由于从未使用过High(即它是单例),因此可以通过将其替换为_ 来重写程序,如下所示:
median(List,Median) :-
dif(List,[]), msort(List,SList), length(List,Len),
append(Low,[Median],Tmp), append(Tmp,_,SList),
length(Low,LowLen), div(Len,2)=:=LowLen, !.
当然,也可以区分列表长度为奇数和偶数的情况,因此在后一种情况下返回两个中值元素的平均值:
median(List,Median) :-
is_list(List), dif(List,[]),
msort(List,SList), length(List,Len),
median(SList,Len,Median).
median(SList,Len,Median) :-
Len mod 2 =:= 1,
append3(Low,[Median],_,SList),
length(Low,LowLen), div(Len,2)=:=LowLen, !.
median(SList,Len,Median) :-
Len mod 2 =:= 0,
append3(Low,[M1,M2],_,SList),
length(Low,LowLen), div(Len,2)=:=LowLen + 1,
Median is (M1+M2)/2, !.
append3(L1,L2,L3,L) :- append(L1,L2,T), append(T,L3,L).