Пролог средний список
У меня есть код, который может рассчитать среднее значение списка, но единственная проблема заключается в том, что он имеет ошибку, когда это пустой список. Я хочу вернуть false, когда список пуст. любой намек?
avg( List, Avg ):-
sum( List, Sum ),
length( List, Length),
Avg is Sum / Length.
4 ответа
Просто добавьте условие, что список не пуст, например:
average( List, Average ):-
sum( List, Sum ),
length( List, Length ),
Length > 0,
Average is Sum / Length.
Это приведет к сбою предиката, что целесообразно, поскольку среднее значение не определено.
Конечно, деление на ноль обычно не допускается. Если (по соглашению) среднее из 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.
avg(список, Avg/1):-
sumlist( List, Sum ),
length( List, Length),
( Length > 0
-> Avg is Sum / Length
; Avg is 0
).
Вы должны разделить среднее значение на 1., например, avg(List, Avg/1). Я просто скопировал его в комментариях выше и добавил avg/2.
Использование аккумулятора, то есть счетчика для вычисления среднего арифметического, может быть полезно для понимания того, как работает 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).