【问题标题】:Haskell get divisors efficiently [duplicate]Haskell有效地获得除数[重复]
【发布时间】:2019-10-19 20:33:49
【问题描述】:

我想有效地找到整数 n 的正确除数。

我该怎么做?

现在我正在使用以下功能

divisors :: (Integral a) => a -> [a]
divisors n = filter ((0 ==) . (n `mod`)) [1 .. (n `div` 2)]

但是我已经读到,当我只检查直到 n 的平方根的数字时,效率会更高。你有什么建议如何用平方根解决它吗?

【问题讨论】:

  • 您当前的函数检查所有数字最多为n 的一半,并且您想更改它以便它检查到n 的平方根?我非常有信心您可以自己解决如何更改您的功能来做到这一点。

标签: haskell


【解决方案1】:

给定一个数n可以被k整除,那么n/kn的除数为好。事实上,因为 n/(n/k)=k。如果 k>√n,我们因此知道 k/n,因此,我们可以每次找到一个除数,而不是计算所有除数,也产生“co-divisor”。

因此我们可以如下实现算法:

divisors :: Integral a => a -> [a]
divisors n = concatMap f (filter ((==) 0 . mod n) (takeWhile (\k -> k*k <= n) [1 .. n]))
    where f k | k < l = [k, l]
              | otherwise = [k]
              where l = div n k

因此,在这里我们首先使用takeWhile (\k -&gt; k*k &lt;= n) [1 .. n] 创建一个从1√n 的列表。

接下来我们过滤这些元素,只保留那些分割n的元素。最后,对于这些元素中的每一个,我们检查协除数是否不同。如果是这种情况,我们将同时产生 k 和 co-divisor l,否则(这将仅适用于 √n),我们只会产生 k

例如:

Prelude Data.List> divisors 1425
[1,1425,3,475,5,285,15,95,19,75,25,57]

【讨论】:

    猜你喜欢
    • 2011-08-14
    • 2015-11-17
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多