【发布时间】:2021-02-25 14:34:16
【问题描述】:
我正在学习 Haskell,目前正在创建一个程序,该程序可以从 3 个不同的 Int:s 中找到所有公约数。 我有一个工作程序,但对大数字的评估时间很长。我想要关于如何优化它的建议。
示例:combineDivisors 234944 246744 144456 == [1,2,4,8]
如前所述,我对此很陌生,因此感谢您提供任何帮助。
import Data.List
combineDivisors :: Int -> Int -> Int -> [Int]
combineDivisors n1 n2 n3 =
mergeSort list
where list = getTrips concList
concList = isDivisor n1 ++ isDivisor n2 ++ isDivisor n3
isDivisor n = [x | x <- [1..n], mod n x == 0]
getTriplets :: Ord a => [a] -> [a]
getTriplets = map head . filter (\l -> length l > 2) . group . sort
--Merge sort--
split :: [a] -> ([a],[a])
split xs =
let
l = length xs `div` 2
in
(take l xs, drop l xs)
merge :: [Int] -> [Int] -> [Int]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| y < x = y : merge (x:xs) ys
| otherwise = x : merge xs (y:ys)
mergeSort :: [Int] -> [Int]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs =
let
(xs1,xs2) = split xs
in
merge (mergeSort xs1) (mergeSort xs2)
【问题讨论】:
-
函数
isDivisor的名称似乎暗示它返回一个布尔值。也许最好使用divisorList。效率:您可以从将数字分解为素数的幂开始。可能在素数上查看Wiki page。