找到在haskell中除以阶乘的数字的最大幂

时间:2017-03-17 16:14:59

标签: algorithm haskell recursion functional-programming

所以我正在编写一个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

但是,我无法弄清楚如何将其作为函数实现,我是使用数组还是只使用简单的递归函数。

我倾向于它只是一个普通的函数,不过我猜它可以通过在数组中存储商并添加它们来完成。

2 个答案:

答案 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。问题是该算法忽略的23的倍数不是6的倍数。但是,如何修复算法是一个完全独立的问题。