所以我正在编写一个haskell程序来计算除以阶乘的数字的最大幂。
largestPower :: Int -> Int -> Int
此处largestPower a b
找到了b
的最大分力a!
。
现在我理解它背后的数学,找到答案的方法是反复将a
(只是a)除以b
,忽略余数并最后添加所有商。所以,如果我们有像
largestPower 10 2
我们应该得到8因为10/2 = 5/2 = 2/2 = 1我们加5 + 2 + 1 = 8
但是,我无法弄清楚如何将其作为函数实现,我是使用数组还是只使用简单的递归函数。
我倾向于它只是一个普通的函数,不过我猜它可以通过在数组中存储商并添加它们来完成。
答案 0 :(得分:2)
您可以简单地编写递归算法并总结每次调用的结果。这里我们有两种情况:
a
小于b
,在这种情况下,最大功率为0
。所以:
largestPower a b | a < b = 0
a
大于或等于b
,在这种情况下,我们将a
除以b
,为该分区计算largestPower
,并将除法添加到结果中。像:
| otherwise = d + largestPower d b
where d = (div a b)
或者把它放在一起:
largestPower a b | a < b = 1
| otherwise = d + largestPower d b
where d = (div a b)
您还可以将递归与累加器一起使用:您通过递归传递的变量,并相应地进行更新。最后,返回该累加器(或在该累加器上调用的函数)。
这里的累加器当然是正在运行的产品,所以:
largestPower = largestPower' 0
因此我们将定义一个函数largestPower'
(注意重音),并将累加器作为第一个参数初始化为1
。
现在在递归中,有两种情况:
a
小于b
,我们只返回累加器:
largestPower' r a b | a < b = r
否则我们将累加器与b
相乘,并通过递归调用将除法传递给largestPower'
:
| otherwise = largestPower' (d+r) d b
where d = (div a b)
或完整版:
largestPower = largestPower' 1
largestPower' r a b | a < b = r
| otherwise = largestPower' (d+r) d b
where d = (div a b)
算法不正确。一个“天真”的算法就是简单地划分每个项目并继续递减,直到达到1
,如:
largestPower 1 _ = 0
largestPower a b = sumPower a + largestPower (a-1) b
where sumPower n | n `mod` b == 0 = 1 + sumPower (div n b)
| otherwise = 0
所以这意味着对于largestPower 4 2
,这可以写成:
largestPower 4 2 = sumPower 4 + sumPower 3 + sumPower 2
和
sumPower 4 = 1 + sumPower 2
= 1 + 1 + sumPower 1
= 1 + 1 + 0
= 2
sumPower 3 = 0
sumPower 2 = 1 + sumPower 1
= 1 + 0
= 1
所以3
。
答案 1 :(得分:0)
所述算法可以非常简单地实现:
largestPower :: Int -> Int -> Int
largestPower 0 b = 0
largestPower a b = d + largestPower d b where d = a `div` b
但是,该算法对于复合b
不正确。例如,使用此算法的largestPower 10 6
会产生1
,但实际上正确的答案是4
。问题是该算法忽略的2
和3
的倍数不是6
的倍数。但是,如何修复算法是一个完全独立的问题。