2016-08-03 28 views
5

Ich bin neu in Prolog und ich versuche, das Prädikat encode(L,L1) zu schreiben, die die Duplikate der Elemente in L zählt, zum Beispiel:Prädikat kodieren in Prolog

encode([4,4,4,3,3],L). 

L=[3,4,2,3]. 

Dies ist, was ich geschrieben habe:

encode(L,L1) :- encode(L,1,L1). 

encode([],_,[]).  
encode([H],N,[N,H]).  
encode([H,H|T],N1,[N,H|T1]) :- M is N1+1, encode([H|T],M,[N,H|T1]).  
encode([H,Y|T],N,[N,H|T1]) :- H\=Y, encode([Y|T],T1). 

Das obige Prädikat ist nicht reversibel. Es funktioniert nur, wenn der erste Parameter bereitgestellt wird.

Wie kann ich encode reversibel schreiben?
Zum Beispiel:

encode(L,[3,4,2,3]).   
L = [4,4,4,3,3]. 
+0

Anstelle von 'M ist N1 + 1' versuchen Sie' M # = N1 + 1'. Stellen Sie sicher, dass Sie das CLP (FD) -Modul laden (': - use_module (library (clpfd)).') Und anstelle von '\ =' '' '' 'verwenden. – lurker

+0

@lurker, Ich versuchte das oben, aber immer noch, nachdem ich die Änderungen vorgenommen habe, bleibt das Problem bestehen: encode (L, [3,4,2,3]) gibt keine Antwort (es löst die Ausnahme "Out of local stack" aus). – coder

Antwort

4

Ich denke, Ihr Algorithmus in einen redundanten Zähler hat. Etwas vereinfacht wäre:

encoded([], []). 
encoded([X], [1,X]). 
encoded([X,Y|T], [1,X|R]) :- 
    dif(X, Y), 
    encoded([Y|T], R). 
encoded([X,X|T], [N,X|R]) :- 
    N #> 1, 
    N #= N1 + 1, 
    encoded([X|T], [N1,X|R]). 

Hinweis in der letzten Klausel müssen wir sicherstellen, dass N größer als 1 als auch.

+0

Vielen Dank !! das hat funktioniert!!! – coder

+1

@coder: Beachten Sie, dass selbst "encoded (Xs, [2, V])." Eine perfekte Antwort liefert! – false

+1

@coder: Und sogar 'codiert (Xs, [2, V, 2, W]).'! Siehst du den "diff" in der vollständigen Antwort? – false