【问题标题】:Prolog find maximum even number in the listProlog在列表中查找最大偶数
【发布时间】:2013-11-16 10:04:03
【问题描述】:

我需要在列表中找到最大偶数。例如

goal: maxEVEN([4,10,-2,-1,23],M).
M=10.

我写了以下代码:

maxeven([],M).
maxeven([X|R],M):- Rest is X mod 2,
                    isRest(Rest, X, M, R).
isRest(0,X,M,[List]):- X > M,
                    maxeven(List,X).
isRest(0,X,M,[List]):- X < M,
                    maxeven(List,M).
isRest(Rest,X,M,[List]):- maxeven(List,M).

它将抛出每个循环成员并检查它是否是偶数,如果它正在检查它是否是创建者而不是已经分配的 M 值。 问题是,对于第一次调用 isRest 谓词,M 的值是空的,这就是它总是返回 false 的原因。我不知道我第一次可以为这个变量分配什么值,这个算法将适用于所有数字。

【问题讨论】:

    标签: list for-loop numbers prolog


    【解决方案1】:

    有一些简单的方法:要么先寻找第一个偶数,然后初始化 M,要么从 M unbound 开始,然后使用 var/1 检查状态。

    但我认为您的代码还有其他问题。这是不寻常的语法:

    isRest(0,X,M,[List]):-..
    

    [List] 它是一个元素的列表,因此我看不出它如何适合您的算法。也许问题是由于您的代码比需要的更复杂。如果我们假设 maxeven/2 在没有偶数的情况下可能失败,那么可以简单为

    maxeven([X|Xs], M) :-
      0 is X mod 2, % fail if not even
      ( maxeven(Xs, T), T > X, !, M = T ; M = X).
    maxeven([_|Xs], M) :-
      maxeven(Xs, M).
    

    这是如何工作的:当 X 是偶数时,尝试查看 Xs 中是否有其他偶数,并进行比较,但如果不存在其他偶数(例如,当 X 是最后一个时),保留X。否则,当X不是偶数时,搜索尾部Xs...

    看看能不能理解为什么需要删减,然后把它移到其他地方,以便更好地理解 Prolog 控制流...不是很直观...

    如果你对 Prolog 感兴趣,别忘了研究它的库:maxeven/2 可以这么简单

    maxeven(Xs, M) :- setof(X, (member(X, Xs), 0 is X mod 2), Evens), last(Evens, M).
    

    【讨论】:

    • 谢谢你帮了我很多
    【解决方案2】:

    这是一个尾递归版本:

    maxeven([X|T], MaxEven) :-
        0 is X mod 2, !,
        maxeven(T, X, MaxEven).
    maxeven([_|T], MaxEven) :-
        maxeven(T, MaxEven).
    maxeven([X|T], LastMax, MaxEven) :-
        0 is X mod 2, !,
        M is max(X, LastMax),
        maxeven(T, M, MaxEven).
    maxeven([_|T], LastMax, MaxEven) :-
        maxeven(T, LastMax, MaxEven).
    maxeven([], LastMax, LastMax).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-24
      • 2013-11-16
      • 1970-01-01
      • 2020-05-13
      • 2017-09-19
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多