使用Haskell的平方和

时间:2014-12-10 17:59:34

标签: haskell

我试图执行以下计算: x:y范围内整数的平方和,其中(x <= y)。

我不确定如何设置约束以确保x小于或等于y。

我需要能够将x的平方加到x + 1:y范围内的平方和中。

我看了几个例子,但是找不到任何严格说明第一个数字必须小于或等于第二个数字,即[1..5]

更新:为了澄清,我不想在函数中硬编码[1..5],但我希望列表是用户的输入。

任何帮助?

由于

3 个答案:

答案 0 :(得分:6)

慢进场

明显而缓慢的方法是实际求和这些方格:

sumOfSquaresSlow :: Integral a => a -> a -> a
sumOfSquaresSlow lo hi
    | lo > hi   = error "sumOfSquaresSlow: lo > hi"
    | otherwise = sum $ map (^2) [lo..hi]

这种方法的时间复杂度在max(y-x,0)中是线性的;如果你的整数范围很大,则需要一段时间;在我的答案底部看到基准。

更快的方法

但是,因为前n个(正)整数的平方和有一个formula,所以你实际上不必逐个对这些正方形求和。

如果x大于y(在your comment中指定),则向用户发出错误消息,您只需使用error功能,此处为

编辑:感谢Chris Drost pointing out that I was overcomplicating things

sumOfSquaresFast :: Integral a => a -> a -> a
sumOfSquaresFast lo hi
    | lo > hi   = error "sumOfSquaresFast: lo > hi"
    | otherwise = ssq hi - ssq (lo - 1)
  where
    ssq x = div (((2 * x + 3) * x + 1) * x) 6

使用此公式可以将复杂性降低到接近恒定时间的程度。

GHCi中的基准

λ> :set +s

λ> sumOfSquaresSlow (10^3)  (10^7)
333333383333002166500
(17.19 secs, 11563005552 bytes)

λ> sumOfSquaresFast (10^3) (10^7)
333333383333002166500
(0.01 secs, 3106112 bytes)

答案 1 :(得分:2)

在GHCI中,请执行以下步骤,了解正在进行的操作:

Prelude> let sq x = x^2
Prelude> let list = [1..5]
Prelude> list
[1,2,3,4,5]
Prelude> let listOfSq = map sq list
Prelude> listOfSq
[1,4,9,16,25]

Prelude> sum listOfSq
55

简写就是Jubobs所说的:

sum $ map (^2) [1..5]

编辑:要在Y大于X时出错,你可以做类似的事情

sumOfSquares :: Integer -> Integer -> Integer
sumOfSquares x y  | y <= x = error "Y must be greater than X"
                  | otherwise = sum $ map (^2) [x..y]

答案 2 :(得分:-1)

使用列表理解:

squareSum from to
  | from > to = error "wrong input"
  | otherwise = sum [i^2 | i <- [from..to]]

更新:OP更新问题后更新