在Prolog中的Lists中,元素的Sum、Average和Count元素的出现次数。

问题描述 投票:1回答:1

如何在Prolog中写出三个谓词,做以下事情。

1)定义 sum (X, N) 谓词,当N是列表X中的整数之和时,它为真。

2)定义 avg (X, N) 谓词,计算列表X中所有元素的算术平均数,其中N为元素数。

3)定义名为 count(X, Y, N),如果列表Y包含N个元素实例X,则为真。

你能给我举出它们的例子,并向我解释为什么它们会这样工作吗?我知道在Stack Overflow上有几十个sum和avg谓词,但我不能真正理解它们为什么工作。

count sum prolog average
1个回答
0
投票

定义 sum(X, N) 谓词,当 N 是列表中的整数之和。X.

你想计算一个列表中元素的和。这个问题最简单的例子是什么?当列表为空时,其元素之和为 0. 我们如何分解较大的列表,以达到简单的情况呢?我们可以去掉列表中的第一个元素,计算剩余列表的和,然后将第一个元素加到结果中。

这种方法可以用下面的代码来实现。

% Simple case: Sum of the empty list
sum([], 0).

% Recursive case: Split list into first element X and remaining list XS
sum([X|XS], N) :- sum(XS, M), N is M + X.

用法:

?- sum([1,2,3],6).
true.
?- sum([1,2,3],X).
X = 6.

用法: is 运算符对它的右手边进行算术计算 (参考),与对待 M + X 作为一个字面的术语。如果你想使用 = 而不是 is, M + X 将被视为一个字面术语。然后你会得到以下输出。

?- sum([1,2,3],6).
false.
?- sum([1,2,3],0+3+2+1).
true.

所以对于Prolog 60+3+2+1 是不同的术语,直到你强行进行算术评估,如由 is.

2)定义avg(X,N)谓词,计算列表X中所有元素的算术平均数,其中N为元素数。

这是不可能的。如果 X 是列表和 N 的元素数,那么这个谓词就没有办法输出平均数(除非你把打印平均数算作一个副作用,我想你不希望这样)。要解决这个问题,可以添加另一个参数 A 代表平均数。avg(X, N, A).

我们可以用列表的总和除以列表的长度来计算平均值。

avg(X, N, A) :- sum(X, S), length(X, N), A is S / N.

用法:

?- avg([1,2,3],3,2).
true.
?- avg([1,2,3,4],N,X).
N = 4,
X = 2.5.

3)定义一个名为count(X, Y, N)的谓词,如果列表Y中包含N个元素实例X,则该谓词为真。

我知道你想要 N 的次数。X 列表中出现 Y. 我们可以再次将其分解为一个简单的情况,然后尝试将一般情况分解成更小的步骤,直到我们得到简单的情况.对于一个空列表,我们知道 X 在该列表中出现零次。对于一个非空的列表,我们可以删除第一个元素,并检查其出现的频率。X 出现在剩余的列表中。如果第一个元素如果等于 X的总出现次数,那么就会出现 X 是1加上剩余列表中的出现次数。如果第一个元素不等于 X的总出现次数,那么就会出现 X 等于剩余列表中的出现次数。

这种方法可以用下面的代码来实现。

% Simple case: The list is empty.
count(_, [], 0).

% Recursive case: First element is equal to X
count(X, [X|YS], N) :- count(X, YS, M), N is M + 1, !.

% Recursive case: First element is unequal to X
count(X, [Y|YS], N) :- X \= Y, count(X, YS, N).

我们用 _ 对于我们不关心的变量。我们也可以写 X 而不是 _但Prolog会给我们一个关于未使用变量的警告。

使用方法:

?- count(1, [1,1,2,3], N).
N = 2.
?- count(2, [1,1,2,3], N).
N = 1.
© www.soinside.com 2019 - 2024. All rights reserved.