计算Haskell中的列表累积和
编写一个函数,返回列表的运行和。e、 g.运行[1,2,3,5]是[1,3,6,11]。我在下面写了这个函数,它可以返回列表中所有值的最终和。那么我如何将它们逐个分开呢计算Haskell中的列表累积和,haskell,Haskell,编写一个函数,返回列表的运行和。e、 g.运行[1,2,3,5]是[1,3,6,11]。我在下面写了这个函数,它可以返回列表中所有值的最终和。那么我如何将它们逐个分开呢 sumlist' xx=aux xx 0 where aux [] a=a aux (x:xs) a=aux xs (a+x) 我认为您需要和(+)的组合,所以 scanl1 (+) *your list here* scanl1将在一个列表中应用给定的函数,并将每个中间值报告到返回的列表中 比如
sumlist' xx=aux xx 0
where aux [] a=a
aux (x:xs) a=aux xs (a+x)
我认为您需要和
(+)
的组合,所以
scanl1 (+) *your list here*
scanl1将在一个列表中应用给定的函数,并将每个中间值报告到返回的列表中
比如,用伪代码写出来
scanl1 (+) [1,2,3]
将输出如下列表:
[1, 1 + 2, 1 + 2 + 3]
换句话说
[1, 3, 6]
有很多很好的例子和描述的扫描,折叠,和更多的哈斯克尔的好东西
希望这能有所帮助。您可以调整函数以生成列表,只需在每个步骤的结果前面加上
a+x
,并使用空列表作为基本情况:
sumlist' xx = aux xx 0
where aux [] a = []
aux (x:xs) a = (a+x) : aux xs (a+x)
不过,Haskell更习惯于将此类内容表示为折叠或扫描。虽然scanl1显然是“规范”解决方案,但了解如何使用foldl实现这一点仍然很有意义:
sumList xs = tail.reverse $ foldl acc [0] xs where
acc (y:ys) x = (x+y):y:ys
或无点:
sumList = tail.reverse.foldl acc [0] where
acc (y:ys) x = (x+y):y:ys
sumList = tail.map sum.inits
这是一种丑陋的暴力手段:
sumList xs = reverse $ acc $ reverse xs where
acc [] = []
acc (x:xs) = (x + sum xs) : acc xs
使用inits
,有一个可爱(但性能不太好)的解决方案:
sumList xs = tail $ map sum $ inits xs
同样是无意义的:
sumList = tail.reverse.foldl acc [0] where
acc (y:ys) x = (x+y):y:ys
sumList = tail.map sum.inits
与我发现的另一个问题相关:
rsum xs = map (\(a,b)->a+b) (zip (0:(rsum xs)) xs)
我认为它甚至非常有效。@sepp2k:如果从列表的右侧开始,那么如何得到左边元素的总和?@Lamdei:对不起,我没想对。然而,不偷懒仍然是不使用foldl(或你的暴力方法)的一个很好的理由。为什么
反向<代码>sumList=(`snd`[])。foldl(\\(a,k)x->(a+x,k.(a+x:))(0,id)
在前进方向上工作得很好。@ephemient:这很酷,我没想到,但对初学者来说可能太复杂了。