如何通过递归计算数字列表的样本均值。实施样本方差?实施样本中位数?
我这样做仅仅是为了样本均值我通过递归,样本方差和样本中位数与样本均值挣扎?谢谢
mean :: [Float] -> Float
mean xs = sum xs / fromIntegral (length xs)
答案 0 :(得分:2)
您可以通过多种方式递归定义{{1}},但我建议的方式可以最大限度地减少效率所需的分割数量:
mean
请注意,虽然经验Haskeller可能会首先编写此代码,但他们可能会使用mean :: [Float] -> Float
mean [] = error "Can't take mean of empty list"
mean xs = go 0 0 xs
where
go len runningSum [] = runningSum / len
go len runningSum (x:xs) = go (len + 1) (runningSum + x) xs
将其转换为删除显式递归并从严格性中受益:
foldl'
这个公式甚至避免了import Data.List (foldl')
mean [] = error "Can't take mean of empty list"
mean xs = uncurry (/) $ foldl' go (0, 0) xs
where go (len, runningSum) x = (len + 1, runningSum + x)
,因为fromIntegral
和len
可以被编译器推断为runningSum
。
对于中位数,递归是一个非常糟糕的工具。使用Float
,Data.List.sort
和length
来实现它会更好。如果您想要涉及递归,请实现快速排序等。如果课程需要它(这看起来很像家庭作业),那么你必须自己弄明白,所以不是家庭作业帮助网站。