Vik*_*ren 4 performance haskell
我实现了这个答案的一个版本/sf/answers/694429781/(我不知道回答的人的意图是什么)
sublistofsize 0 _ = [[]]
sublistofsize _ [] = []
sublistofsize n (x : xs) = sublistsThatStartWithX ++ sublistsThatDontStartWithX
where sublistsThatStartWithX = map (x:) $ sublistofsize (n-1) xs
sublistsThatDontStartWithX = sublistofsize n xs
Run Code Online (Sandbox Code Playgroud)
我不确定的是什么 sublistsThatStartWithX = map (x:) $ sublistofsize (n-1) xs
我假设map(x :)在性能方面提出了问题,但不确定如何解决它.我做过剖析print $ length $ sublistofsize 5 $ primesToTakeFrom 50
COST CENTRE MODULE no. entries %time %alloc %time %alloc
sublistofsize Main 112 4739871 46.9 39.9 96.9 100.0
sublistofsize.sublistsThatDontStartWithX Main 124 2369935 2.2 0.0 2.2 0.0
sublistofsize.sublistsThatStartWithX Main 116 2369935 47.8 60.1 47.8 60.1
Run Code Online (Sandbox Code Playgroud)
我是否以良好的方式实施了它?有没有更快的方法呢?
Ber*_*rgi 14
我假设map(x :)给出了一个明智的问题
编号map有效编码并以线性时间运行,此处没有问题.
但是,您的递归可能是一个问题.你们都调用sublistofsize (n-1) xs和sublistofsize n xs,这-发出启动列表sublistofsize m (_:_:ys)-不评价长期sublistofsize (m-1) ys的两倍,因为在不同的递归步骤,它们之间没有共享.
所以我应用动态编程来获取
subsequencesOfSize :: Int -> [a] -> [[a]]
subsequencesOfSize n xs = let l = length xs
in if n>l then [] else subsequencesBySize xs !! (l-n)
where
subsequencesBySize [] = [[[]]]
subsequencesBySize (x:xs) = let next = subsequencesBySize xs
in zipWith (++) ([]:next) (map (map (x:)) next ++ [[]])
Run Code Online (Sandbox Code Playgroud)
不是附加空列表是最美丽的解决方案,但你可以看到我如何使用zipWith移位列表,以便结果next使用两次 - 一次直接在长度为n的子序列列表中,一次在子序列列表中长度为n + 1.
在GHCI中进行测试:set +s,您可以看到这比天真的解决方案更快:
*Main> length $ subsequencesOfSize 7 [1..25]
480700
(0.25 secs, 74132648 bytes)
(0.28 secs, 73524928 bytes)
(0.30 secs, 73529004 bytes)
*Main> length $ sublistofsize 7 [1..25] -- @Vixen (question)
480700
(3.03 secs, 470779436 bytes)
(3.35 secs, 470602932 bytes)
(3.14 secs, 470747656 bytes)
*Main> length $ sublistofsize' 7 [1..25] -- @Ganesh
480700
(2.00 secs, 193610388 bytes)
(2.00 secs, 193681472 bytes)
*Main> length $ subseq 7 [1..25] -- @user5402
480700
(3.07 secs, 485941092 bytes)
(3.07 secs, 486279608 bytes)
Run Code Online (Sandbox Code Playgroud)