2013-11-16 5 views
1

Мне нужно найти максимальное число в списке. НапримерПролог найти максимальное число в списке

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. Я не знаю, какое значение я могу присвоить этой переменной в первый раз, когда этот алгоритм будет работать со всеми числами.

ответ

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 ... Это не очень интуитивно понятно ...

Если вы заинтересованы в Прологе, не забудьте изучить его библиотеку: maxeven/2 может быть столь же просто, как

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

Спасибо, Вы мне очень помогли – kuldarim

1

Вот хвост рекурсивной версии:

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). 
Смежные вопросы