Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 整数n的除数列表(Haskell)_Performance_Haskell_Primes_Factors_Factorization - Fatal编程技术网

Performance 整数n的除数列表(Haskell)

Performance 整数n的除数列表(Haskell),performance,haskell,primes,factors,factorization,Performance,Haskell,Primes,Factors,Factorization,我目前使用以下函数获取整数的除数: -- All divisors of a number divisors :: Integer -> [Integer] divisors 1 = [1] divisors n = firstHalf ++ secondHalf where firstHalf = filter (divides n) (candidates n) secondHalf = filter (\d -> n `div` d /= d) (m

我目前使用以下函数获取整数的除数:

-- All divisors of a number
divisors :: Integer -> [Integer]
divisors 1 = [1]
divisors n = firstHalf ++ secondHalf
    where firstHalf = filter (divides n) (candidates n)
          secondHalf = filter (\d -> n `div` d /= d) (map (n `div`) (reverse firstHalf))
          candidates n = takeWhile (\d -> d * d <= n) [1..n] 
——一个数的所有除数
除数::整数->[整数]
除数1=[1]
除数n=上半部分++下半部分
其中前半部分=过滤器(除以n)(n)
secondHalf=filter(\d->n`div`d/=d)(映射(n`div`)(反向上半部分))

候选者n=takeWhile(\d->d*d测量瓶颈所在,将三个辅助定义(前半部分、后半部分、候选者)放在顶层,并在分析器上运行代码:
ghc-prof--make divisors.hs
/divisors 100+RTS-p-RTS

也知道,最大的候选是<代码> Sqt N,所以不要做很多乘法<代码> d*d>代码>,只考虑<代码> [1….Load(qrt n)] < /代码>

为了得到更好的算法,你应该带一本数学书,因为这不是一个与哈斯克尔有关的问题……你可以考虑的事情:如果“a除以b”,那么对于a的所有除数d,d也除以b。 如果给定的d除以b,您需要使用记忆或动态编程来避免多次检查(例如,如果15和27除以b,那么您只需要在数学上检查3除以b一次。其他时候,您只需查看3是否在b的除数表中).

您不必测试反向后半部分的所有元素。您知道,如果平方根存在,那么它就是那里的头元素:

          secondHalf = let (r:ds) = [n `div` d | d <- reverse firstHalf]
                       in [r | n `div` r /= r] ++ ds
这样我们就可以免费获得下半场,作为制作上半场的一部分

但这很难成为应用程序中的瓶颈,因为算法本身效率很低。通常更快。通过尝试除法进行素因子分解可以更快,因为我们将发现的每个除数进行除法,从而减少被分解的数,从而减少尝试的除数(直到减少的数字的平方根)。例如,
12348=2*2*3*3*7*7
并且在分解过程中不尝试高于
7
的因子,而在
divs 12348
中,数字12348被从
2
110
的所有数字所除:

factorize n=go n(2:[3,5..])--或:(go n素数)其中
其中--primes=2:
go n ds@(d:t)——过滤器(null.tail.factorize)[3,5..]
|d*d>n=[n]
|r==0=d:go q ds
|否则=去
式中(q,r)=quotRem n d