Prolog:按备用索引对列表进行排序

时间:2015-03-19 22:25:20

标签: list sorting prolog

我尝试按给定的优先顺序对颜色列表进行排序。例如,以[z,b,g,r,w]的顺序排序的列表[r,z,z,w,g,g,r,z]将给出[z,z,z的最终结果, G,G,R,R,]瓦特
我尝试使用基本的bubblesort算法并添加一个检查,以查看前两个术语中哪一个更高'更高'在订单清单上。

% take the to-sorted list, the order in which to sort the list, and the
% result. 
%colourSort([r,z,z,w,g,g,r,z],[z,b,g,r,w],X). returns X = [z,z,z,g,g,r,r,w]

colourSort(List,Order,Sorted):-
    swap(List,List1,Order),
    !,
    colourSort(List1,Order,Sorted).

colourSort(Sorted,_,Sorted).

% check if the either the first or second letter is first in the order
% list, if neither check the next letter in the order list. 
check(A,_,[H|_],A):-
    A == H.
check(_,B,[H|_],B):-
    B == H.
check(A,B,[_|T],R):-
    check(A,B,T,R).
check(_,_,[],_).


%swap incase a set of letters isn't ordered, continues otherwise.
swap([X,Y|Rest],[Y,X|Rest],Order):-
    check(X,Y,Order,R),
    X == R.
swap([Z|Rest],[Z|Rest1],Order) :-
    swap(Rest,Rest1,Order).

当我运行代码时,它最终导致我的swi-prolog崩溃,我假设它被卡在一个循环或其他东西中,但是我们无法弄清楚为什么或者怎么样。
任何建议或提示将不胜感激。

1 个答案:

答案 0 :(得分:3)

这是解决所述问题的解决方案,但不使用自定义排序算法。相反,它使用常见的pairs数据结构(使用(-)/2运算符构成项目列表Key-Value)和keysort/2进行排序。 修改:这个答案已经根据评论中的@mat的提示进行了重新设计,并提供了更简洁的解释。)

解决方案:

item_with_rank(Ranking, Item, Rank-Item) :-
    nth0(Rank, Ranking, Item).

sort_by_ranking(Ranking, ToSort, Sorted) :-
    maplist(item_with_rank(Ranking), ToSort, Ranked),
    keysort(Ranked, RankedSorted),
    pairs_values(RankedSorted, Sorted).

说明:

我们定义一个谓词item_with_rank(Ranking, Item, Rank-Item),它使用任意排序的术语列表作为Ranking,并与给定的Item a Rank相关联,相当于0 Ranking中与Item统一的第一个词的索引。然后我们定义sort_by_ranking(Ranking, ToSort, Sorted)sort_by_ranking/3使用maplist/3在列表item_with_rank/3的每个元素上使用给定的Ranking来调用ToSort,获取对的列表{{1} },为每个项目分配一个等级。我们使用Rankedkeysort/2进行排序,以便它们的元素顺序符合其" rank"的值。 ({1}}中的(键)。当我们仅从Ranked中提取值时,我们会留下RankedSorted项,这就是我们所追求的:

使用示例:

RankedSorted