1

所以我一直在研究以下问题:

编写一个 3 位谓词 scalarMult,其第一个参数是整数,第二个参数是整数列表,第三个参数是第二个参数与第一个参数相乘的结果。例如,查询

?-  scalarMult(3,[2,7,4],Result). 

应该产生

Result = [6,21,12] 

在累加器和包装谓词的帮助下做到这一点。

这就是我所做的:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], List2).

scalarMult1(I,[], A, A).
scalarMult1(I,[H|T], A, Result):- H1 is H*I, scalarMult1(I,T,[H1|A],Result).

唯一的问题是它将新元素放在累加器的头部,所以我最终得到了一个反向列表(所以对于上面的例子,我会得到 Result = [12,21,6])。有什么办法可以解决这个问题吗?我尝试在我的代码中使用 reverse,但我所有的尝试都失败了。

谢谢

4

2 回答 2

2

使用 reverse/2 作品,实际上:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], T), reverse(T, List2).

但我认为使用累加器的要求(在这里真的没用)可能是为了验证您的列表处理水平。

于 2014-02-27T13:19:07.430 回答
1

scalar_multiplication/3注意到 Carlo 关于将累加器用于教学目的的评论,谓词的直接定义不需要累加器(重命名为scalarMult/3;骆驼案例在 Prolog 中不被认为是好的编程风格):

% first exchange argument orders to take advantage of the first-argument
% indexing that is provided in most Prolog implementations
scalar_multiplication(Scalar, Numbers, ScaledNumbers) :-
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

% base case; either input list was empty or we finished traversing the list
scalar_multiplication_([], _, []).

% recursive case
scalar_multiplication_([Number| Numbers], Scalar, [ScaledNumber| ScaledNumbers]) :-
    ScaledNumber is Number * Scalar,
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

这是处理列表的常见模式的一个实例。如此普遍以至于几个 Prolog 实现提供了一个二阶谓词(或元谓词),通常命名为map/3ormaplist/3来处理它。

于 2014-02-27T14:18:12.590 回答