排序卡片列表prolog

时间:2012-08-07 18:49:47

标签: prolog bubble-sort

我有一个卡片结构列表,例如:

[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不是数字

1 个答案:

答案 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]

如何?给定两个值AB,我们只需使用nth0/3在列表中搜索ABnth0/3将为我们提供我们正在搜索的元素的位置。所以现在:

X = position of the element A in the ordered list
Y = position of the element B in the ordered list

但现在XY保证是数字!我们可以将它们与内置谓词compare/3进行比较。如果X < YA出现在卡B之前,反之亦然。

compare/3会比较XY,并返回(>)(<)(=)中的一个。

一个例子:

?- compare_values(D, card(ace, clubs), card(7, spades)). 
  • nth0在有序值列表中搜索ace7
  • 现在X = 0Y = 6(列表中ace7的索引)
  • 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)].