如何从左到右获得列表的产品? 例如:
?- product([1,2,3,4], P).
P = [1, 2, 6, 24] .
我认为一种方法是重载仿函数并使用3个参数:
product([H|T], Lst) :- product(T, H, Lst).
我不确定从哪里开始。
答案 0 :(得分:3)
您可以使用此处找到的库(lambda):http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl 相当难以理解:
:- use_module(library(lambda)).
:- use_module(library(clpfd)).
product(L, R) :-
foldl(\X^Y^Z^(Y = []
-> Z = [X, [X]]
; Y = [M, Lst],
T #= X * M,
append(Lst, [T], Lst1),
Z = [T, Lst1]),
L, [], [_, R]).
感谢@Mike_Hartl的建议,代码很简单:
product([], []).
product([H | T], R) :-
scanl(\X^Y^Z^( Z #= X * Y), T, H, R).
答案 1 :(得分:2)
似乎是一个列表副本,只是乘以最后处理的元素。让我们从最开始的元素开始:
product(L, P) :-
product(L, 1, P).
product([X|Xs], A, [Y|Ys]) :-
Y is X * A,
product(Xs, Y, Ys).
product([], _, []).
如果我们使用库(clpfd):
:- [library(clpfd)].
product([X|Xs], A, [Y|Ys]) :-
Y #= X * A,
product(Xs, Y, Ys).
product([], _, []).
它有效(仅适用于整数)'后退'
?- product(L, [1,2,6,24]).
L = [1, 2, 3, 4].
答案 2 :(得分:1)
可能非常脏的解决方案(我是Prolog的新手):
product([ListHead|ListTail], Answer) :-
product_acc(ListTail, [ListHead], Answer).
product_acc([ListHead|ListTail], [AccHead|AccTail], Answer) :-
Product is ListHead * AccHead,
append([Product, AccHead], AccTail, TempList),
product_acc(ListTail, TempList, Answer).
product_acc([], ReversedList, Answer) :-
reverse(ReversedList, Answer).
所以基本上在开始时我们称之为另一个谓词 额外的“变量”Acc是累加器列表。
因此我们从原始列表中取出头(第一个数字)并将其放入 到累加器列表。
然后我们总是从原始列表中取头(第一个数字) 将它与累加器列表中的头(第一个数字)相乘。
然后我们必须追加我们通过乘法获得的新数字 头部来自蓄能器,后来带尾部
然后我们再次调用相同的谓词,直到原始列表变空 最后我们显然需要扭转它。
似乎有效
?- product([1,2,3,4], L).
L = [1, 2, 6, 24].
?- product([5], L).
L = [5].
?- product([5,4,3], L).
L = [5, 20, 60].
很抱歉,如果我的解释不是很清楚。随意评论。