【问题标题】:Find elements before X on list查找列表中 X 之前的元素
【发布时间】:2018-04-07 14:57:55
【问题描述】:

我正在学习 Prolog,这可能是一个非常简单的问题。

假设我只需要一个执行以下操作的过程:

before(5, [1, 2, 4, 5, 36, 5], Result)
...
Result = [1, 2, 4, 5]

我知道如果 N 是第一个元素,我可以添加以下规则:

before(N, [N|_], Result) :- Result = [N].

但是对于其他情况我该怎么办?

【问题讨论】:

  • 在另一种情况下,第二个参数是一个列表[X|Tail],其中X 也是整个结果列表的首位。剩下的就是找到(通过递归)Tail 列表的结果列表。
  • 谢谢@IsabelleNewbie。然后我有before(N, [X|Tail], Result)。我的想法是将 X 添加到结果列表中,直到 X 为 N,但是对于我阅读的内容,我无法在定义变量后更改它。你能帮忙吗?
  • 如果你有[X|Tail]并且N不是X,那么结果必须是[X|ResultTail]的形式。
  • 谢谢@IsabelleNewbie。现在工作!
  • 简单的解决方案是:before(N, L, Result) :- once(append(Result, [N|_], List)).

标签: prolog logic


【解决方案1】:

一个非常简单的解决方案:

before( _, [], []).
before( N, [N|_], [N]).
before( N, [X|T], [X|Res]):- dif(N,X), before( N, T, Res).

例子:

?- before(5, [1, 2, 4, 5, 36, 5], Result).
Result = [1, 2, 4, 5] ;
false.

还有一个使用来自library(reif)if_/3 的更优雅的解决方案:

:- use_module(library(reif)).

before( _, []   , [] ).
before( N, [X|T], Res):- 
            if_( X = N, 
                 Res = [N],
                 (before( N, T, Res2), Res = [X|Res2] )
               ).

例子:

?- before(5, [1, 2, 4, 5, 36, 5], Result).
Result = [1, 2, 4, 5].

如您所见,这是确定性的,它只给出了一个答案,没有留下选择点。在第一个答案中给出了相同的结果,但有一个选择点返回错误。第二个答案给出了正确的结果,避免了这个无用的选择点,效率更高。同样在

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 2011-01-24
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    相关资源
    最近更新 更多