【问题标题】:Prolog to check if list is sorted (ascending or descending)Prolog 检查列表是否已排序(升序或降序)
【发布时间】:2021-10-02 03:38:56
【问题描述】:

我想编写一个谓词来确定列表是否已排序(升序或降序都将返回 true)

is_sorted([]).
is_sorted([_]).
is_sorted([X,Y|T]):-X=<Y, is_sorted([Y|T]).

当我只想检查一个特定的订单时,这很有效,我如何将它用于升序和降序?

【问题讨论】:

  • 结果必须是确定性的吗?
  • 是的,它必须是
  • 问题与artificial-intelligence 无关 - 请不要向无关标签发送垃圾邮件(已删除)。

标签: sorting prolog


【解决方案1】:

只要在列表中找到第一对不同的相邻元素,您就可以使用compare/3 实例化顺序(升序或降序)。

sorted(L) :- sorted(L, _).

sorted([], _).
sorted([_], _) :- !.
sorted([X,X|R], Order) :- !, sorted([X|R], Order).
sorted([X,Y|R], Order) :- compare(Order, X, Y), sorted([Y|R], Order).

例子:

?- sorted([ann, bob, coy]).
true.

?- sorted([coy, bob, bob, ann]).
true.

?- sorted([coy, bob, dan, bob, ann]).
false.

?- sorted([1, 2, 3, 3, 3, 4]).
true.

?- sorted([4, 3, 2, 1]).
true.

?- sorted([1-coy, 2-ann, 3-bob]).
true.

?- sorted([5-coy, 4-ann, 3-bob]).
true.

?- sorted([1-coy, 4-ann, 3-bob]).
false.

【讨论】:

    【解决方案2】:

    您可以将订单谓词传递给is_sorted

    is_sorted(_, []).
    is_sorted(_, [_]).
    is_sorted(P, [X,Y|T]):- call(P, X, Y), is_sorted(P, [Y|T]).
    

    这里P 可以是任何带有两个参数的谓词。

    ?- is_sorted(=<, [1, 2, 3, 4, 4]).
    true 
    ?- is_sorted(<, [1, 2, 3, 4, 4]).
    false.
    
    ?- is_sorted(>, [4, 3, 1, 0, -2]).
    true 
    ?- is_sorted(@<, [hey, how]).
    true 
    ?- is_sorted(@<, [hey, how, are]).
    false.
    

    检查列表是按升序还是降序排序:

    sorted_any([]).
    sorted_any([_]).
    sorted_any([X, Y | T]) :-
        (X = Y) -> sorted_any([Y|T]);
        (
        (X < Y) -> is_sorted(=<, [Y|T]);
        is_sorted(>=, [Y|T])
        ).
    

    【讨论】:

    • 谢谢,但在这里你已经假设了顺序,我正在尝试编写一个谓词,如果它的排序与顺序无关,它将给我 true,如果不是,则为 false
    • 您可以在列表的前两个元素上使用 compare/3 来“播种”顺序(&lt;=&gt; 之一),然后使用该顺序检查如果其余元素的顺序相同。 compare/3 更通用,因为它是为任何两个 Prolog 术语定义的,因此您不必关心 @&lt;&lt; 之类的问题。您也不需要任何条件。
    • @User9213 : sorted([X,Y|T]) :- compare(O, X, Y), is_sorted(O, [Y|T]). ,这非常适合严格的订单。对于=&lt;&gt;=,我还需要条件句。
    • @rajashekar 好点。如果您有一系列相等的元素,然后是更大或更小的东西,那么您的解决方案会发生什么?例如[a,a,a,b] vs [b,b,b,a]?
    • @User9213 :我认为 sorted_any 在任一列表上都成功了。我们应该在最后一次迭代中有is_sorted(=&lt;, [b])is_sorted(&gt;=, [a]),这两个都是真的。有问题吗?
    【解决方案3】:

    寻找不需要统一列表头部和尾部的解决方案通常是一个好主意。这消除了使用切割的需要,以避免在评估期间留下选择点。

    sorted([]).
    sorted([H|T]) :- sorted(T, H, _).
    
    sorted([], _, _).
    sorted([H|T], Last, Dir) :-
        compare(Dir1, H, Last),
        (   Dir1 = (=)
        ->  true
        ;   Dir1 = Dir),
        sorted(T, H, Dir).
    

    【讨论】:

      【解决方案4】:

      判断一个列表是否按升序排序很简单:

      ordered_ascending( []       ) .  % the empty list is ordered in ascending sequence.
      ordered_ascending( [X]      ) .  % A list of length 1 is ordered in ascending sequence.
      ordered_ascending( [A,B|Cs] ) :- % A list of length > 1 is ordered if...
        A @=< B ,                      % A is less than or equal to B, and
        ordered_ascending( [B|Cs] ) .  % the remainder of the list (less A) is similarly ordered.
      

      同样,判断一个列表是否按降序排列也同样简单:

      ordered_descending( []       ) .  % the empty list is ordered in ascending sequence.
      ordered_descending( [X]      ) .  % A list of length 1 is ordered in ascending sequence.
      ordered_descending( [A,B|Cs] ) :- % A list of length > 1 is ordered if...
        A @>= B ,                       % A is greater than or equal to B, and
        ordered_descending( [B|Cs] ) .  % the remainder of the list (less A) is similarly ordered.
      

      添加一个包装器以提供所需的确定性,一切就绪:

      ordered( Xs ) :- ordered_ascending(  Xs ) , ! .
      ordered( Xs ) :- ordered_descending( Xs ) , ! .
      

      您可以通过向包装器添加一些智能来提高效率:

      ordered( []  ) .
      ordered( [X] ) .
      ordered( [X,Y|Zs] ) :- X @=< Y , ordered_ascending(  [Y|Zs] ) , ! .
      ordered( [X,Y|Zs] ) :- X @>= Y , ordered_descending( [Y|Zs] ) , ! .
      

      你会注意到我在这里丢弃了列表的第一个元素,因为 我们不需要再次测试它。

      【讨论】:

        猜你喜欢
        • 2018-04-25
        • 2021-03-27
        • 2020-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-17
        相关资源
        最近更新 更多