Wie findet man das N-te element einer Liste in Prolog
Ich bin versucht, schreiben Sie ein Prolog-code finden Sie die n-te element einer Liste.
Ich schrieb den code unten, aber es nicht zurückgeben, das element rechts.
match([Elem|Tail],Num,Num,Elem).
match([Elem|Tail],Num,C,MatchedNumber):-
match(Tail,Num,N,Elem),
C is N+1.
In der ersten Zeile sage ich, wenn das gewünschte element Anzahl ist gleich zu kontern, dann geben Sie das erste element der aktuellen Liste an die variable namens MatchedNumber
. Dieser code gibt die Num
und Counter
Recht, aber ich weiß nicht, warum, wenn ich einstellen will MatchedNumber
als Elem
, es gibt immer das erste element der Liste.
1: was ist falsch an diesem code?
2: Wie kann ich sagen, dass anstatt zu zeigen, die aufeinander abgestimmt Reihe, entfernen Sie es aus der Liste?
InformationsquelleAutor Amir Jalilifard | 2015-05-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste von allen, es ist ein builtin
nth0/3
:Holen Sie sich die ich-te element
Das problem ist im induktiven Fall ist:
Prolog nicht wissen, etwas über
C
so die Letzte Aussage doens T-force-Prolog-die Rückkehr der ich-te element. Es kann schicken Sie einfach ein beliebiges element, weilN
passenNum
im rekursiven Aufruf und legen Sie dannC
zuNum+1
aber das ist nicht ein problem, weilC
ist nicht gebunden an irgendetwas.Einen besseren Weg, um dieses Problem zu lösen, ist die Verwendung eines Dekrementieren Zähler:
Beispiel:
Base case ist also, dass der index
0
in dem Fall kehren Sie die Kopf, da Sie sonst die Abfrage für die i-1-te element des Schwanzes. Dies ist auch ein deklarativer Ansatz.Dieser Ansatz nutzt auch tail recursion, die in der Regel steigern die Leistung deutlich.
Änderung der ursprünglichen Prädikat
Ist es eher un-Prolog Verwendung eines iterator und ein gebunden, eine im Allgemeinen verwendet einen reverse-iterator.
Können Sie jedoch ändern, das Prädikat wie folgt:
So ein paar Fehler:
!
in der ersten Klausel: denn wenn es stimmt, wissen wir Prolog sollte nicht versuchen, die zweite;MatchedNumber
im rekursiven Aufruf stattElem
;Count < Num
,Count1 is Count+1
vor dem rekursiven Aufruf; und_
.Beispiel ist dann:
Aber wie gesagt, es ist ineffizient, übergeben Sie ein zusätzliches argument, etc.
Entfernen Sie die ich-te element aus der Liste
Eine fast gleiche Ansatz kann verwendet werden, um die zu entfernen ich-te element aus der Liste:
Hier die Basis-Fall ist wieder, dass der index
0
in welchem Falle der Schwanz von der Liste entfernt wird (damit fallen den Kopf). Der induktive Fall legen Sie den Kopf der Liste in den Kopf der resultierenden Liste und zählen auf den rekursiven Aufruf von entfernen den richtigen Gegenstand aus dem Schwanz. Ein weiteres base-caseremovei([],_,[]).
wird Hinzugefügt, weil es möglich ist, dass ich größer ist als die Länge der Liste, in dem Fall das Prädikat wird nicht entfernen Sie alle Artikel.Beispiel
Meine Frage ist nur, wie kann ich die Bearbeiten mein code um dieses problem zu lösen?
Diese Versionen sind nicht standhaft.
in der Tat, man kann mit einem negativen index oder verwenden Sie ankten Variablen.
Auch der zweite Tipp ist: welchen Wert Sie berechnen möchten mit
is
?N
oderC
...InformationsquelleAutor Willem Van Onsem
Finden der N-te element einer Liste (wo
n
ist relativ zu null), so etwas wie dies sollte ausreichen:Ähnlich, entfernen Sie das N-te element einer Liste, so etwas wie dies sollte ausreichen:
InformationsquelleAutor Nicholas Carey