2017-04-10 11 views
1

so bin ich ziemlich neu zu Prolog und ich muss alle Elemente einer Liste zusammenzählen.Hinzufügen von Elementen einer Liste in Prolog

listSum([],0). 
listSum([Head|Tail], Sum) :- listSum(Tail,TailSum), Sum is Head + TailSum. 

Das Ziel ist, diese Schwanz-rekursiv zu machen und ich habe mich gefragt, ob das eine bessere Art und Weise war es, als dies oder

listSum([],0). 
listSum(List, Sum) :- listSum(List,Sum,0). 
listSum([H|T], Sum, S) :- S1 is S+H, listSum(T, Sum, S1). 
listSum([], Sum, S) :- Sum is S. 

zu tun ist, dass völlig in Ordnung zu tun? Nur um zu sehen, ob es einen offensichtlichen Weg gibt, den obigen Code zu verbessern, den ich verpasse.

Danke.

Antwort

2

Das sieht für mich vollkommen in Ordnung aus. Sie können sich etwas schreiben, indem Sie nicht unnötige Dinge tun. Zuerst bekommst du 0 von zwei verschiedenen Orten; es wäre genug, um es von einem zu bekommen. Auch "Output" -Argumente sollen nach allen anderen Argumenten kommen.

list_sum(L, S) :- 
    list_sum(L, 0, S). 

Dann brauchen Sie nicht die is/2 im Basisfall:

list_sum([], S, S). 
list_sum([X|Xs], S0, S) :- 
    S1 is S0 + X, 
    list_sum(Xs, S1, S). 

Natürlich könnten Sie entscheiden, tatsächlich einen Schritt in der tail-rekursive Definition speichern:

list_sum([], 0). 
list_sum([X|Xs], S) :- 
    list_sum(Xs, X, S). 

list_sum([], S0, S) :- S is S0. 
list_sum([X|Xs], S0, S) :- 
    S1 is S0 + X, 
    list_sum(Xs, S1, S). 

Sie sollten erkennen, dass die zweite Version eine Falte ist:

list_sum([], 0). 
list_sum([X|Xs], S) :- 
    foldl(add, Xs, X, S). 

add(X, Y, S) :- S is X+Y. 

Oder sogar direkt:

list_sum(List, Sum) :- foldl(add, List, 0, Sum). 
+0

Wunderbar, danke für die schnelle und große Antwort :) – mvantastic

Verwandte Themen