查找列表中最大的偶数

时间:2016-12-22 13:17:42

标签: prolog

该程序的重​​点应该是找到列表中最大的偶数。例如,查询:

? - evenmax([1, 3, 9, 16, 25, -5, 18], X]
X = 18.

我想这样做的方法是将列表分成两个,一个只有奇数,一个只有偶数。但是,在这样做之后,我理所当然不知道如何具体取偶数列表并找到最大整数。

以下是我目前的情况:

seperate_list([], [], []).
separate_list([X|Xs], [X|Even], Odd) :-
    0 is X mod 2,
    separate_list(Xs, Even, Odd).
separate_list([X|Xs], Even, [X|Odd]) :-
    1 is X mod 2,
    separate_list(Xs, Even, Odd).

find_max([X|Xs], A, Max).
    X  >  A,
    find_max(Xs,X,Max).
find_max([X|Xs],A,Max) :-
    X  =<  A,
    find_max(Xs,A,Max).
find_max([],A,A).

我仍然是Prolog的新手,所以请耐心等待......我感谢你的帮助。

4 个答案:

答案 0 :(得分:2)

你可以一气呵成。您可以在列表中找到第一个偶数,然后将其用作种子,并在列表的其余部分中找到最大的偶数。

但是如果你不坚持在列表中进行单次遍历,你可以先收集所有偶数,然后按降序排序并获取排序列表的第一个元素。

evenmax(List, M) :-
        include(even, List, Even),
        sort(Even, Sorted),
        reverse(Sorted, [M|_]).

even(E) :-
        E rem 2 =:= 0.

如果您想了解include/2的实施方式,可以look here。基本上,这是您已在问题中定义的separate_list/3的通用和优化版本。 sort/2是内置的,reverse/2是库谓词implementation is here

还有很多其他方法可以实现相同的目标,但对于初学者来说这应该足够好了。如果您想要更具体的答案,您应该询问更具体的问题,例如:

  • 如果列表中包含自由变量怎么办?
  • 如果您想按降序排序而不是排序然后倒车怎么办?
  • 如何一次性完成?

等等。

答案 1 :(得分:1)

很抱歉,但是......如果您需要最大(偶数)值...为什么不扫描列表,记住最大(偶数)值?

我看到的真正问题是:当没有偶数值时,价值会回归。

在以下示例中,我使用-1000作为最小值(如果没有偶数值)

evenmax([], -1000).  % or a adeguate minimum value

evenmax([H | T], EM) :-
  K is H mod 2,
  K == 0,
  evenmax(T, EM0),
  EM is max(H, EM0).

evenmax([H | T], EM) :-
  K is H mod 2,
  K == 1,
  evenmax(T, EM).

- 编辑 -

鲍里斯是对的:前面是一个糟糕的解决方案。

遵循他的建议(谢谢!)我完全重写了我的解决方案。再长一点,但(恕我直言)好多了

evenmaxH([], 1, EM, EM).

evenmaxH([H | T], 0, _, EM) :-
  0 =:= H mod 2,
  evenmaxH(T, 1, H, EM).

evenmaxH([H | T], 1, M0, EM) :-
  0 =:= H mod 2,
  M1 is max(M0, H),
  evenmaxH(T, 1, M1, EM).

evenmaxH([H | T], Found, M, EM) :-
  1 =:= H mod 2,
  evenmaxH(T, Found, M, EM).

evenmax(L, EM) :-
  evenmaxH(L, 0, 0, EM).

答案 2 :(得分:1)

我定义evenmax,就像没有列表L的成员,它是偶数且大于X:

memb([X|_], X).
memb([_|T], X) :- memb(T,X).
even(X) :- R is X mod 2, R == 0. 
evenmax(L, X) :- memb(L, X), even(X), not((memb(L, Y), even(Y), Y > X)), !. 

答案 3 :(得分:0)

已经有很多好的答案,但没有一个能够回答你问题的这一部分:

  

我合法地不知道如何取偶数列表   具体而言,找到

中的最大整数

根据你的谓词定义,它就是这样:

evenmax(List, EvenMax) :-
    separate_list(List, Evens, _Odds),
    find_max(Evens, EvenMax).

对于这个find_max/2,您还需要添加一个小小的定义:

find_max([X|Xs], Max) :-
    find_max(Xs, X, Max).

最后,您的代码中存在一些拼写错误:单独与单独拼写,并且在子句头中有.而不是:-