List 序言:按备选索引对列表排序
我试图按照给定的优先顺序对颜色列表进行排序。例如,按此顺序排序的列表[r,z,z,w,g,g,r,z]将给出[z,z,z,g,g,r,r,w]的最终结果。List 序言:按备选索引对列表排序,list,sorting,prolog,List,Sorting,Prolog,我试图按照给定的优先顺序对颜色列表进行排序。例如,按此顺序排序的列表[r,z,z,w,g,g,r,z]将给出[z,z,z,g,g,r,r,w]的最终结果。 我尝试使用一个基本的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
我尝试使用一个基本的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,我假设它被卡在循环中或是其他什么东西中,但我还没有弄清楚原因或方式
如果您有任何建议或提示,我们将不胜感激。以下是所述问题的解决方案,但它不使用自定义排序算法。相反,它使用公共数据结构(使用
(-)/2
运算符形成项目列表键值
),并使用键排序/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\u和_rank(Ranking,item,rank item)
,它使用一系列任意顺序的术语作为排名
,并与给定的项
a排名
相关联,这相当于排名
中与项
相统一的第一个术语的基于0的索引。然后我们定义sort\u by\u ranking(ranking,ToSort,Sorted)
sort\u by_ranking/3
使用maplist/3
调用item\u,在列表的每个元素ToSort
上使用给定的排名
,获得一个成对的列表,排名
,为每个项目分配一个排名。我们使用keysort/2
对RankedSorted
中的RankedSorted
进行排序,以便元素的顺序与它们的“ranks”(键)值一致。当我们仅从RankedSorted
中提取值时,剩下的是已排序的
项,这就是我们所追求的:
用法示例:
?- sort_by_ranking([z,b,g,r,w], [r,z,z,w,g,g,r,z], S).
S = [z, z, z, g, g, r, r, w] ;
false.
在colorsort/3
的第一个子句中,它调用swap/3
,然后生成List1
,然后使用List1
递归调用colourSort/3
。如果swap/3
没有减少List1
相对于List
的长度,那么这将无限重复。逻辑似乎假设如果不交换任何东西,swap
将失败,但我不认为是这样。所以循环是因为它没有找到一条退出交换循环的路?对于prolog和构建基本bubblesort的ColorSort还是一个新手,所以假设它也能工作。bubbleSort(列表,已排序):-swap(列表,列表1)!,bubbleSort(列表1,已排序)。bubbleSort(已排序,已排序)。交换([X,Y | Rest],[Y,X | Rest]):-X>Y。交换([Z | Rest],[Z | Rest1]):-swap(Rest,Rest1)。在注释中粘贴代码似乎也很糟糕:/我不知道这是否是您唯一的循环问题,但这正是我第一次读到它时突然想到的。如果您使用trace
,您可能会看到详细的情况在注释中粘贴代码是错误的。不可读。如果您需要详细说明代码,您应该编辑问题并将其张贴在那里,格式正确。+1,非常好的解决方案!略短一点:将单个项目的排名、项目和关键项目对之间的关系描述为item\u with\u rank/3
,然后使用maplist(item\u with\u rank(ranking)、List、KeyList)
@mat Good call。我到家后再加上那个零钱。谢谢:)