2010-12-07 14 views
7

ich mit Prologs spielen bin ab, und mit einem Java-Hintergrund ist es wirklich schwierig für mich, so dass hier eine dumme Frage:Wie berechnen Index des Elements in einer Liste?

Wie werden Sie ein indexOf Prädikat der Lage zu geben, den Index eines bestimmten Elements in einem bestimmten schreiben Liste ?

Meine erste Frage ist über das Prädikat arity: Ich denke, es sollte 3 sein wie:

indexOf(List,Element, Index) :- ...... 

Bin ich richtig? Vielleicht existiert das bereits in eingebauten Bibliotheken, aber ich möchte lernen, wie man es schreibt. Danke für Ihre Hilfe.

+0

wie ein guter Anfang aussieht. – aschepler

+0

@aschepler ja, aber ich bin verrückt, dieses kleine Prädikat zu haben, das funktioniert !!! –

+0

Dies ist in der Tat eine gute Übung beim Lernen von Prolog. Zu Ihrer Information: Die Bauprädikate, um dies zu erreichen, sind 'nth0' und' nth1'. (http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%27A.12%27,swi%28%27/doc/Manual/lists.html%27%29%29) – Cephalopod

Antwort

11

Sie können es rekursiv tun: Angenommen 0-basierten Index (sonst nur die 0 auf dem ersten Satz mit 1 ändern)

indexOf([Element|_], Element, 0). % We found the element 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), % Check in the tail of the list 
    Index is Index1+1. % and increment the resulting index 

Wenn Sie nur den ersten Auftritt finden möchten, können Sie einen Schnitt hinzufügen könnten (!) um Backtracking zu vermeiden.

indexOf([Element|_], Element, 0):- !. 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), 
    !, 
    Index is Index1+1. 
+0

danke für die Antwort. Kann ich die erste Klausel durch folgende ersetzen: indexOf ([First | _], Element, Index): - First == Element, Index == 0.? –

+0

Die Antwort ist NEIN. Kannst du erklären warum ? –

+0

Der Operator == führt keine Vereinheitlichung durch. Daher kann der Index nicht auf 0 instanziiert werden. Er kann jedoch im ersten Vergleich verwendet werden (First == Element wäre in Ordnung, weil in diesem Prädikat beide Begriffe instanziiert werden sollten). Index == 0 schlägt fehl, wenn Index nicht instanziiert wird. – gusbro

1

Man sollte lieber Schwanz-Rekursion verwenden:

indexOf(V, [H|T], A, I) 
:- 
    Value = H, A = I, ! 
; 
    ANew is A + 1, 
    indexOf(V, T, ANew, I) 
. 

indexOf(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
. 

indexOfWithoutFailure(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
; 
    Index = -1 
. 

Einige Beispielabfragen:

?- indexOf(d, [a, b, c, d, e, f], Index). 
Index = 3. 

?- indexOf(x, [a, b, c, d, e, f], Index). 
false. 

?- indexOfWithoutFailure(x, [a, b, c, d, e, f], Index). 
Index = -1. 

Wenn Sie alle Indizes eines Elements in einer Liste erhalten möchten, sollten Sie schreibe ein anderes Prädikat dafür ohne den Schnitt namens allIndexesOf oder so.

0

Ich habe dies in Notation Nachfolger und es ist ziemlich präzise und ordentlich:

index([V|_],V,0). 
index([_|T],V,s(I)) :- index(T,V,I). 

Probe Ausgänge:

?- index([a,b,c,a],a,X). 
X = 0 ; 
X = s(s(s(0))) ; 
false. 

?- index(List,a,s(0)). 
List = [_G1710, a|_G1714]. 
Verwandte Themen