Определение двух предложений, чтобы найти максимальное число в списке - PullRequest
6 голосов
/ 29 ноября 2009

Как бы я написал рекурсивное определение из двух предложений, чтобы найти максимальное значение в списке. Пока я написал это:

 max(L,M):-  

 max([H|T],M):-

max(T,H,M).
max([],M,M).
max([H|T],Y,M):-
   H =< Y,
   max(T,Y,M).
max([H|T],Y,M):-
   H > Y,
   max(T,H,M).

Это не работает, оно говорит, что есть синтаксическая ошибка, которую я не совсем вижу, и я знаю, что это не два предложения. Кто-нибудь знает, как я мог бы упростить это, чтобы сделать это двумя пунктами?

Ответы [ 8 ]

10 голосов
/ 29 ноября 2009

Как и вы, я использую имя 'max' для предиката. Эта реализация не зависит от встроенного предиката:

max([X],X).
max([X|Xs],X):- max(Xs,Y), X >=Y.
max([X|Xs],N):- max(Xs,N), N > X.
5 голосов
/ 29 ноября 2009

Синтаксическая ошибка возникает из-за того, что первые два предложения не имеют тела.

Чтобы ответить на ваш вопрос, обратите внимание, что максимум списка можно определить индуктивно следующим образом:

  • Максимум списка с одним элементом - это элемент.
  • Максимум списка с несколькими элементами - это наибольшее из головы и максимальное из хвоста.

Таким образом,

max_list([H], H).
max_list([H|T], M2) :- 
  max_list(T, M),
  M2 is max(H, M).

В этом коде используется max/2 ( SWI-Prolog , GNU-Prolog ). Обратите внимание, что большинство или все реализации Prolog будут иметь встроенную функцию max_list/2 ( S , G ), поэтому на самом деле нет необходимости определять ее самостоятельно.

Редактировать: Бакоре отмечает , что хвостовая рекурсивная реализация может быть более эффективной. Вы можете сделать это, определив предикат max_list/3, который принимает дополнительный аргумент C, а именно наибольшее значение, которое когда-либо наблюдалось.

max_list([H|T], M) :- max_list(T, H, M). 

max_list([], C, C).
max_list([H|T], C, M) :- C2 is max(C, H), max_list(T, C2, M).
1 голос
/ 02 декабря 2012

Этот работает точно

l:-listing.
m(L,X):-aku2(L,0,X).
aku2([],B,B).
aku2([G|O],Maks,C):-maks(Maks,G,Maks1),aku2(O,Maks1,C).
maks(A,B,C):-A>B, C is A.
maks(A,B,C):-A=<B, C is B.
1 голос
/ 24 апреля 2011

ДОМЕНЫ

num=INTEGER
list = num*

Предикаты

nondeterm maxList(list,num)

КЛАУЗЫ

maxList([A],A).   
maxList([A|List],Max):- Max=A,maxList(List,Max1),A>=Max1.  
maxList([A|List],Max):- Max=Max1,
maxList(List,Max1),A< Max1.

ЦЕЛЬ

maxList([1,2,3,5,4],Max).
1 голос
/ 18 ноября 2010

Вот решение для max в списках списков

max_list([], C, C).
max_list([H|T], C, M) :- C2 is max(C, H), max_list(T, C2, M).

max_list([], []).
max_list([[H|HB]|B],[RH|RB]) :- max_list(HB, H, RH), max_list(B, RB).

ex: max_list([[1,3,6], [6,3,8,2],[2,1,0]]).
0 голосов
/ 06 ноября 2013

Я знаю, что этот вопрос старый, но вот ответ с использованием конструкции if-then-else:

maxmember([X],X).
maxmember([H|T],Max) :- maxmember(T, M),(H>M -> Max is H ; Max is M).
0 голосов
/ 03 ноября 2013
list([H],H).
list([H1,H2|T],X):-H1>H2,list([H1|T],X).
list([_|T],X):-list(T,X).

Цель: list([3,9,4,5],M)

Выход: M=9

0 голосов
/ 22 сентября 2011

Я думаю, что код ниже решит проблему:

max_list([],0).
max_list([H],H).
max_list([H|T],M):- max_list(T,M1),M is max(H,M1).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...