2009-11-29 3 views
6

Wie würde ich eine rekursive Zwei-Satz-Definition schreiben, um den Maximalwert in einer Liste zu finden. Bisher habe ich dieses geschrieben habe:Zwei-Klausel-Definition, um die maximale Anzahl in einer Liste zu finden

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). 

dies nicht funktioniert, sagt, es gibt es einen Syntaxfehler, die ich nicht ganz sehen können, und ich weiß es auch nicht zwei Klausel ist. Wer weiß, wie ich es vereinfachen könnte, um es zu zweit zu machen?

+1

Wenn diese Hausaufgaben ist, sollten Sie Fügen Sie der Frage das Tag "Hausaufgabe" hinzu. –

+0

Nein, das sind keine Hausaufgaben, es ist nur eine grundlegende Schwierigkeit, die ich beim Versuch, Prolog zu verwenden, gefunden habe. – Taylor

Antwort

5

Der Syntaxfehler ergibt sich aus der Tatsache, dass die ersten beiden Klauseln keinen Rumpf haben.

Um Ihre Frage zu beantworten, beachten Sie, dass das Maximum einer Liste induktiv wie folgt definiert werden:

  • Das Maximum einer Liste mit einem Element, das Element ist.
  • Das Maximum einer Liste mit mehreren Elementen ist der größte des Kopfes und das Maximum des Schwanzes. So

,

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

Dieser Code verwendet max/2 (SWI-Prolog, GNU-Prolog). Beachten Sie, dass die meisten oder alle Prolog-Implementierungen eine integrierte Funktion max_list/2 (, G) haben, so dass es eigentlich nicht notwendig ist, sie selbst zu definieren.

Bearbeiten:Bakore notes, dass eine tail rekursive Implementierung effizienter sein kann. Sie können das tun, indem Sie ein Prädikat max_list/3 definieren, das ein zusätzliches Argument C nimmt, nämlich den größten bisher gesehenen Wert.

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). 
10

Wie Sie, verwende ich den 'max' Namen für das Prädikat.Diese Implementierung verlassen Sie sich nicht in jedem Einbau-Prädikat:

max([X],X). 
max([X|Xs],X):- max(Xs,Y), X >=Y. 
max([X|Xs],N):- max(Xs,N), N > X. 
+2

Es ist effizienter, wenn Sie am Ende der ersten Zeile einen Schnitt einfügen: max ([X], X): - !. –

+3

Hey Mann, kannst du erklären, was hier vor sich geht? –

1

Hier ist eine Lösung für max in Listen von Listen

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]]). 
1

DOMÄNEN

num=INTEGER 
list = num* 

PREDICATES

nondeterm maxList(list,num) 

KLAUSELN

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. 

GOAL

maxList([1,2,3,5,4],Max). 
0

Ich denke, der folgende Code wird das Problem lösen:

max_list([],0). 
max_list([H],H). 
max_list([H|T],M):- max_list(T,M1),M is max(H,M1). 
+0

Was sollte 'max_list ([- 1], M)' sein? Nach Ihrer Definition: 'M = 0' und' M = -1'. – false

1

Dieses sicher

arbeitet
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. 
+0

-1: 'm ([- 1, -2], M)' ergibt 'M = 0' – false

-2
list([H],H). 
list([H1,H2|T],X):-H1>H2,list([H1|T],X). 
list([_|T],X):-list(T,X). 

Ziel: list([3,9,4,5],M)

Ausgang: M=9

+0

Wie funktioniert das und wie verbessert es sich bei anderen Antworten? – Mark

+0

-1: 'liste ([3,2,1], M)' ergibt 'M = 3; M = 1; M = 2; M = 1 ' – false

0

weiß, dass ich diese Frage ist alt, aber hier ist eine Antwort, die if-then-else-Konstrukt mit:

maxmember([X],X). 
maxmember([H|T],Max) :- maxmember(T, M),(H>M -> Max is H ; Max is M). 
Verwandte Themen