sort([ [30,100], [10,11] ], X).
X = [[10,11],[30,100]]
我如何排序只能通过每个子列表的第一个指数?
即
X = [[10,100], [30, 11]]
感谢
sort([ [30,100], [10,11] ], X).
X = [[10,11],[30,100]]
我如何排序只能通过每个子列表的第一个指数?
即
X = [[10,100], [30, 11]]
感谢
下面是我未经测试的代码..有可能是一/二化妆错误...输入列表是基于该头价值分成两列表和结果两个列表递归处理,最终得到排序的输出。
sort(Input,Output):-sort(Input,[],Output).
sort([],SortedOut,SortedOut).
sort([[Index1,Index2]|Tail],SortedBig,Out):-
split(Tail,[Index1,Index2],LessList,BigList),
!,sort(BigList,SortedBig,NewSort),
sort(LessList,[[Index1,Index2]|NewSort],Out).
split([],[_D],[],[]).
split([[Index1,Index2]|Rem],[Index21,Index22],[[Index1,Index1]|L1],L2):-
Index1<Index21,
!,split(Rem,[Index21,Index22],L1,L2).
split([[Index1,Index2]|Rem],[Index21,Index22],L1,[[Index1,Index1]|L2]):-
!,split(Rem,[Index21,Index22],L1,L2).
试试这个,让我知道...
型的简单方法应当仔细阅读可用建宏。然后在第一个元素从各个子表,对它们进行排序,并在原有的替换:
sortfirst(L, S) :-
maplist(get_first, L, A),
msort(A, B),
maplist(set_first, L, B, S).
get_first([E|_], E).
set_first([_|R], E, [E|R]).
编辑:注意,要求msort,以避免失去重复。
测试:
?- sortfirst([ [30,100], [10,11] ], X).
X = [[10, 100], [30, 11]].
的get/set第一只是需要从MAPLIST调整参数:如果我们使用lambda,我们可以写一个真正的 '一个内胆' 过程:
:- [lambda].
sortfirst_lambda(L, S) :-
maplist(\X^Y^(X = [E|_], Y = E), L, A),
msort(A, B),
maplist(\X^Y^Z^(X = [_|R], Y = E, Z = [E|R]), L, B, S).
简单的身份可以简化一些表达式:
sortfirst_lambda(L, S) :-
maplist(\X^Y^(X = [Y|_]), L, A),
msort(A, B),
maplist(\X^Y^Z^(X = [_|R], Z = [Y|R]), L, B, S).
编辑:或者更简单:
sortfirst_lambda(L, S) :-
maplist(\[Y|_]^Y^true, L, A),
msort(A, B),
maplist(\[_|R]^Y^[Y|R]^true, L, B, S).
在这里你可以看到,在原来的GET /先设置,需要的参数,就统一。
因此拉姆达它的语法方便,但有代价的:
?- randomlists(100000, 3, -30,+30, L),
time(sortfirst(L,A)),
time(sortfirst_lambda(L,B)),
assertion(A=B).
% 400,012 inferences, 0,482 CPU in 0,483 seconds (100% CPU, 830072 Lips)
% 1,700,012 inferences, 1,717 CPU in 1,721 seconds (100% CPU, 990302 Lips)
L = [[-8, -13, 11], [-13, -27, -29], [5, 10, -24], [-8, -7, -6], [3, -24, -9], [-13, -20, -24], [7, 27|...], [-5|...], [...|...]|...],
A = B, B = [[-30, -13, 11], [-30, -27, -29], [-30, 10, -24], [-30, -7, -6], [-30, -24, -9], [-30, -20, -24], [-30, 27|...], [-30|...], [...|...]|...].
这里的服务谓词建立大小的测试数据:
randomlist(Length, Low, High, List) :-
findall(E, (between(1, Length, _),
random(Low, High, E)), List).
randomlists(Length1, Length2, Low, High, ListOfLists) :-
findall(E, (between(1, Length1, _),
randomlist(Length2, Low, High, E)), ListOfLists).
@chac(+1 BTW):有没有需要拉姆达到一行这个(在swi中至少有!):
sortfirst(L, Res) :-
maplist(selectchk, X, L, R),
msort(X, XS),
maplist(selectchk, XS, Res, R).
但是lambda版本或者你的第一个ve我认为rsion不那么棘手,可读性更强。
谢谢,我不知道selectchk! – CapelliC 2012-03-09 11:24:56
假设你有[[10,12],[10,11]]。什么是期望的输出? [[10,12],[10,11]]是否可以输出?您是否正在根据排序顺序更改列表的第一个元素,并按原样保留每个列表的其余部分? – 2012-03-09 04:13:04
是的,忽略第二个索引,只对每个子列表的第一个排序。 – CyberShot 2012-03-09 04:15:02
我不知道有这样做的任何标准功能。您可能必须编写自己的自定义谓词。步骤是将每个列表的尾部存储在一个新列表中,将头部保存在一个新列表中,对头部列表进行排序并附加两个结果列表 – 2012-03-09 04:21:05