所以我一直在研究以下问题:
写一个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但是我的所有尝试都失败了。
由于
答案 0 :(得分:2)
使用reverse / 2工作,实际上:
scalarMult(I, List1, List2):- scalarMult1(I, List1, [], T), reverse(T, List2).
但我认为使用累加器(这里真的没用)的要求可能是为了验证你的列表处理水平。
答案 1 :(得分:1)
注意到Carlo关于使用累加器用于教学目的的说法,scalar_multiplication/3
谓词的直接定义不需要累加器(从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/3
或maplist/3
来处理它。