1

我有能够计算列表平均值的代码,但唯一的问题是它在为空列表时会出错。当列表为空时,我想返回 false。任何提示?

avg( List, Avg ):- 
    sum( List, Sum ),
    length( List, Length), 
    Avg is Sum / Length.
4

4 回答 4

3

当然,通常不允许除以零。如果(按照惯例)0 个元素的平均值可以为 0,则可能的修正是

avg( List, Avg ):- 
    sum( List, Sum ),
    length( List, Length), 
    (  Length > 0
    -> Avg is Sum / Length
    ;  Avg is 0
    ).

编辑我在 SWI-Prolog 中测试,将 sum/2 替换为 sumlist/2

avg( List, Avg ):-
    sumlist( List, Sum ),
    length( List, Length),
    (  Length > 0
    -> Avg is Sum / Length
    ;  Avg is 0
    ).

测试:

?- avg([1,2,3],X).
X = 2.

?- avg([],X).
X = 0.

编辑对不起,我忽略了false空输入列表所需的内容。然后测试是否Length > 0肯定是合适的。谓词将失败。

使用库(聚合)的替代方法:

?- L=[1,2,3,4,5], aggregate((count,sum(N)),member(N,L),(Count,SumN)), Ave is SumN/Count.
L = [1, 2, 3, 4, 5],
Count = 5,
SumN = 15,
Ave = 3.
于 2012-10-06T09:10:45.677 回答
3

只需添加一个列表不为空的条件,例如:

average( List, Average ):- 
    sum( List, Sum ),
    length( List, Length ),
    Length > 0, 
    Average is Sum / Length.

这将导致谓词失败,这是适当的,因为平均值未定义。

于 2012-10-06T09:27:19.853 回答
0

使用累加器,意思是一个计数器来实现算术平均值可能有助于理解 Prolog 的工作原理。

mean([],0). % an empty list would have mean 0

mean(Xs,Mean):- % define the predicate with a list, and the mean output
  % pass the original list, mean output, and adds two counters
  % the counters should start at 0 for accumulation
  mean1(Xs,0,0,Mean). 

% base case, after recursion, the list would be empty
% the counter would accumulate the number of elements and
% the sum of the elements
mean1([],Count,Sum,Mean):- 
  Mean is Sum / Count.

% basic recursion to track the EleCount, plus 1 each time
% the Sum would add the X in the Xs each time, until Xs is empty
mean1([X|Xs],EleCount,Sum,Mean):-
  NewCount is EleCount + 1,
  NewSum is Sum + X,
  mean1(Xs,NewCount,NewSum,Mean).
于 2021-05-22T03:52:46.513 回答
0

平均(列表,平均/ 1): -

sumlist( List, Sum ),

length( List, Length),

(  Length > 0
-> Avg is Sum / Length
;  Avg is 0
).  

您应该将平均值除以 1。例如 avg(List, Avg/1)。我只是在上面的评论中复制了它并添加了 avg/2。

于 2016-08-01T07:06:24.713 回答