我有一个卡片结构列表,例如:
[card(ace, spades), card(10, diamonds), card(king, clubs)]
任何人都可以帮我理解如何根据面值对这些进行排序吗?
我有这个:
bubblesort(L, L1) :-
( bubble(L, L2)
-> bubblesort(L2, L1)
; L = L1 ).
bubble([card(A,A2), card(B,B2)|T], L) :-
( A > B
-> L = [card(B,B2), card(A,A2)|T]
; L = [card(A,A2) | L1],
bubble([card(B,B2)|T], L1)).
效果很好(其冒泡排序),除非card(ace, spades)
或类似因为ace
不是数字
答案 0 :(得分:3)
您可以使用predsort/3
它就像sort/2
,但通过调用您提供的比较谓词来确定术语的顺序。因此,我们只需要编写一个compare_values/3
谓词来比较卡片的面值。我的尝试:
compare_values(D, card(A,_), card(B,_)) :-
nth0(X, [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king], A),
nth0(Y, [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king], B),
compare(D, X, Y).
sort_cards(L, R) :-
predsort(compare_values, L, R).
compare_values/3
谓词的解释:
我们需要在以下列表中定义一个排序:
[ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]
如何?给定两个值A
和B
,我们只需使用nth0/3
在列表中搜索A
和B
。 nth0/3
将为我们提供我们正在搜索的元素的位置。所以现在:
X = position of the element A in the ordered list
Y = position of the element B in the ordered list
但现在X
和Y
保证是数字!我们可以将它们与内置谓词compare/3
进行比较。如果X < Y
卡A
出现在卡B
之前,反之亦然。
compare/3
会比较X
和Y
,并返回(>)
,(<)
,(=)
中的一个。
一个例子:
?- compare_values(D, card(ace, clubs), card(7, spades)).
nth0
在有序值列表中搜索ace
和7
。 X = 0
和Y = 6
(列表中ace
和7
的索引)compare(D, 0, 6)
与D = (<)
最后:predsort/3
谓词使用compare_values根据定义的顺序by compare_values/3
查询:
?- sort_cards([card(king, spades), card(ace,spades), card(3, clubs), card(7,diamonds), card(jack,clubs)], X).
X = [card(ace, spades), card(3, clubs), card(7, diamonds), card(jack, clubs), card(king, spades)].