2016-10-10 1 views
2

Zum Beispiel:
positions (X, L, R):- .Wie kann ich die Indizes speichern, wo eine Nummer in einer Liste von Prolog erscheint?

Wo:

  1. X die Zahl ist, die ich suche.
  2. L ist eine Liste vieler Zahlen.
  3. R ist die Liste, die die Indizes speichert, wobei X
  4. erscheint

ich diese bekam, aber es spielt keine „Rückkehr“ eine Liste, es gibt mir nur einzelne Ergebnisse:

pos(X,[X|_],0). 
pos(,[],):- !,fail. pos(X,[_|R],Pos):- pos(X,R,Pos1), Pos is Pos1+1. 
+0

Haben Sie schon etwas probiert? – dasblinkenlight

+0

Nun, ich habe das, aber es gibt keine Liste zurück, es gibt mir nur einzelne Ergebnisse: 'pos (X, [X | _], 0). pos (_, [], _): - !, Fehlgeschlagen. pos (X, [_ | R], Po): - pos (X, R, Pos1), Pos sind Pos1 + 1.' '- po (0, [1,2, 0,1,0], R). R = 2; R = 4; false.' – Pablisky

+1

Das ist perfekt! Bei SO geht es darum, Code zu posten, der noch nicht funktioniert. – dasblinkenlight

Antwort

0

Wenn Sie Zugriff auf nth0/3 oder nth1/3 haben, kann es verwendet werden, um „zu finden“ die Positionen eines Elements in einer Liste. Zum Beispiel:

?- List = [0,1,2,3,0,4,5,0], nth0(N, List, 0). 
List = [0, 1, 2, 3, 0, 4, 5, 0], 
N = 0 ; 
N = 4 ; 
N = 7. 

Alles was Sie brauchen, ist alle Antworten in einer Liste zu sammeln. Verwenden Sie einfach bagof/3:

?- List = [0,1,2,3,0,4,5,0], bagof(N, nth0(N, List, 0), Ns). 
List = [0, 1, 2, 3, 0, 4, 5, 0], 
Ns = [0, 4, 7]. 

definieren Sie können es als ein Prädikat wie folgt aus:

positions(X, L, R) :- 
    bagof(N, nth0(N, L, X), R). 

Im Gegensatz zu den anderen Lösungen, können Sie diese verwenden, um die Positionen von jedem Element in der Liste zu finden auf Rückzieher:

?- positions(X, [0,1,2,0,2], R). 
X = 0, 
R = [0, 3] ; 
X = 1, 
R = [1] ; 
X = 2, 
R = [2, 4]. 

Wenn Sie nicht wollen, nth0/3 zu verwenden, gehen Sie einfach weiter und Ihre eigene definiti verwenden von pos/3, stellen Sie einfach sicher, dass es tut, was es sollte. Siehe zum Beispiel die answer to the third of the 99 Prolog problems: es ist eine geradlinige Implementierung von . Sie müssen nur die 1 zu 0 ändern, um 0-basierte Indizes zu erhalten.Es ist fast identisch mit dem, was Sie bereits hatten (wie in Ihrer Frage gezeigt).

+0

Es auch funktioniert !! – Pablisky

0

Ich denke, Sie brauchen einen Index und creare R akkumulieren die passenden Indizes.

von Beispiel

positionH(_, _, [], []). 

positionH(I, X, [Y | Tl], Tr):- 
    Y \= X, 
    Ip1 is I+1, 
    positionH(Ip1, X, Tl, Tr). 

positionH(I, X, [X | Tl], [I | Tr]):- 
    Ip1 is I+1, 
    positionH(Ip1, X, Tl, Tr). 

position(X, L, R):- 
    positionH(0, X, L, R). 
0

Sie können Ihren Code wie folgt ändern:

positions(X, L, R) :- positions(X, L, R, 1). 

positions(_, [], [], _). 
positions(X, [X|T], [I|R], I) :- plus(I, 1, N), positions(X, T, R, N). 
positions(X, [Y|T], R, I) :- X \= Y, plus(I, 1, N), positions(X, T, R, N). 

Demo.

Die positions/3 Klausel gibt es den aktuellen Index I zu positions/4 Regel hinzuzufügen.

Die drei Klauseln positions/4 sind wie folgt:

  • Die erste, Base, Klausel ist für eine leere Liste
  • Die zweite Klausel ist das Anfangselement zur Anpassung an X
  • Die dritte Klausel Um zum nächsten Element zu wechseln, wenn keine Übereinstimmung vorhanden ist (zB X \= Y).
+0

Dies ist, was ich gesucht habe, die einzige Änderung, die ich getan habe, ist auf den ersten Index, weil es 0 sein musste, aber ich habe diesen Code bereits geändert. TU !! – Pablisky

+0

Funktioniert das, wenn Sie es mit einer freien Variable im ersten Argument abfragen? –

+0

@Boris Ich sehe es nicht als eine Voraussetzung. – dasblinkenlight

Verwandte Themen