对嵌套列表降序排序
Sorting a nested List Descending order
我有这个嵌套列表:
Xs = [ [Joe, Pilot, 100], [Stan, Co-Pilot, 300], [Steve, Pilot, 150], ].
我如何排序这个嵌套列表以便执行以下操作:(按降序使用第三个元素)
Xs = [ [Stan, Co-Pilot, 300], [Steve, Pilot, 150], [Joe, Pilot, 100] ]. ?
定义:
criteria(R,[_,_,N1],[_,_,N2]) :- compare(R,N2,N1).
并使用 "predsort/3",如:
?- predsort(criteria,[ [Joe, Pilot, 100], [Stan, Co-Pilot, 300], [Steve, Pilot, 150] ], Xs).
Xs = [[Stan, Co-Pilot, 300], [Steve, Pilot, 150], [Joe, Pilot, 100]].
如果存在重复的第三个元素,"criteria" 必须更改。例如:
criteria(R,[_,_,N1],[_,_,N2]) :- N1=\=N2, !, compare(R,N2,N1).
criteria(R,E1,E2) :- compare(R,E1,E2).
如果您将数据表示更改为结构(无论如何这是一个好主意),并且您的 Prolog 系统具有 sort/4
(例如 ECLiPSe, SWI),您可以简单地执行:
?- Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)],
sort(3, >=, Xs, Ys).
Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)]
Ys = [emp(stan, copilot, 300), emp(steve, pilot, 150), emp(joe, pilot, 100)]
Yes (0.00s cpu)
一种更便携的 (ISO) 方法是将每个列表元素与排序键配对,然后使用 keysort/2,然后再次剥离键:
?- Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)],
add_keys(Xs, KXs),
keysort(KXs, KYs),
strip_keys(KYs, Ys).
Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)]
KXs = [-100 - emp(joe, pilot, 100), -300 - emp(stan, copilot, 300), -150 - emp(steve, pilot, 150)]
KYs = [-300 - emp(stan, copilot, 300), -150 - emp(steve, pilot, 150), -100 - emp(joe, pilot, 100)]
Ys = [emp(stan, copilot, 300), emp(steve, pilot, 150), emp(joe, pilot, 100)]
Yes (0.00s cpu)
使用辅助谓词
add_keys([], []).
add_keys([Emp|Emps], [Key-Emp|SEmps]) :-
Emp = emp(_Name,_Job,Salary),
Key is -Salary,
add_keys(Emps, SEmps).
strip_keys([], []).
strip_keys([_-V|KVs], [V|Vs]) :-
strip_keys(KVs, Vs).
我有这个嵌套列表:
Xs = [ [Joe, Pilot, 100], [Stan, Co-Pilot, 300], [Steve, Pilot, 150], ].
我如何排序这个嵌套列表以便执行以下操作:(按降序使用第三个元素)
Xs = [ [Stan, Co-Pilot, 300], [Steve, Pilot, 150], [Joe, Pilot, 100] ]. ?
定义:
criteria(R,[_,_,N1],[_,_,N2]) :- compare(R,N2,N1).
并使用 "predsort/3",如:
?- predsort(criteria,[ [Joe, Pilot, 100], [Stan, Co-Pilot, 300], [Steve, Pilot, 150] ], Xs).
Xs = [[Stan, Co-Pilot, 300], [Steve, Pilot, 150], [Joe, Pilot, 100]].
如果存在重复的第三个元素,"criteria" 必须更改。例如:
criteria(R,[_,_,N1],[_,_,N2]) :- N1=\=N2, !, compare(R,N2,N1).
criteria(R,E1,E2) :- compare(R,E1,E2).
如果您将数据表示更改为结构(无论如何这是一个好主意),并且您的 Prolog 系统具有 sort/4
(例如 ECLiPSe, SWI),您可以简单地执行:
?- Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)],
sort(3, >=, Xs, Ys).
Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)]
Ys = [emp(stan, copilot, 300), emp(steve, pilot, 150), emp(joe, pilot, 100)]
Yes (0.00s cpu)
一种更便携的 (ISO) 方法是将每个列表元素与排序键配对,然后使用 keysort/2,然后再次剥离键:
?- Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)],
add_keys(Xs, KXs),
keysort(KXs, KYs),
strip_keys(KYs, Ys).
Xs = [emp(joe, pilot, 100), emp(stan, copilot, 300), emp(steve, pilot, 150)]
KXs = [-100 - emp(joe, pilot, 100), -300 - emp(stan, copilot, 300), -150 - emp(steve, pilot, 150)]
KYs = [-300 - emp(stan, copilot, 300), -150 - emp(steve, pilot, 150), -100 - emp(joe, pilot, 100)]
Ys = [emp(stan, copilot, 300), emp(steve, pilot, 150), emp(joe, pilot, 100)]
Yes (0.00s cpu)
使用辅助谓词
add_keys([], []).
add_keys([Emp|Emps], [Key-Emp|SEmps]) :-
Emp = emp(_Name,_Job,Salary),
Key is -Salary,
add_keys(Emps, SEmps).
strip_keys([], []).
strip_keys([_-V|KVs], [V|Vs]) :-
strip_keys(KVs, Vs).