从左到右获取列表的产品

时间:2013-02-28 22:20:43

标签: prolog

如何从左到右获得列表的产品? 例如:

?- product([1,2,3,4], P).
P = [1, 2, 6, 24] .

我认为一种方法是重载仿函数并使用3个参数:

product([H|T], Lst) :- product(T, H, Lst).

我不确定从哪里开始。

3 个答案:

答案 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].

很抱歉,如果我的解释不是很清楚。随意评论。