我有这个代码来计算m:n
范围内的整数平方和sumsquares :: Integral a=> Int -> Int -> Int -> Int
sumsquares m n middle
| m > n = error "First number cannot be bigger than second number"
|m==n = m*m
|otherwise = m*m + sumsquares (m+1)n
我如何为此目的重新定义函数sumsquares?
如果m:n范围内有多个数字,则计算范围的中间值,并将(m:middle)的平方和加到平方和(中间+ 1:n), 否则m:n范围内只有一个数,所以m = = n,解是m的平方。 (注意,使用这种方法,递归结合了两个半解:每个子问题大约是整个问题的一半)。
答案 0 :(得分:3)
在原始函数中,类型签名中的类约束Integral a
已过时(签名中的任何其他位置都没有提到a
,是吗?)。此外,函数的第三个参数(middle
)仍未使用。因此,你可以把它写成
sumsquares :: Int -> Int -> Int
sumsquares m n
| m > n = error "First number cannot be bigger than second number"
| m == n = m * m
| otherwise = m * m + sumsquares (m + 1) n
重写它以从decrease-and-conquer方案转变为严格的分而治之计划,然后只需相应地调整递归案例:
sumsquares :: Int -> Int -> Int
sumsquares m n
| m > n = error "First number cannot be bigger than second number"
| m == n = m * m
| otherwise = let middle = (m + n) `div` 2
in sumsquares m middle + sumsquares (middle + 1) n
当然,问题仍然是你想要做出这种改变的原因。一个原因可能是你正在准备你的算法以适应并行化:那么,实际上,分而治之通常比减少和征服更合适。