如何优化这种随机播放功能?

时间:2015-09-12 18:55:49

标签: haskell shuffle

我正在尝试使用Haskell创建泛型(type-o-polymophism?)shuffle函数。我需要在几分之一秒内对几千个元素进行排序才能被认为足够好"。

evens :: [a] -> [a]
evens l = [l !! i | i <- [0,2..(length l) - 1]]

odds :: [a] -> [a]
odds  l = [l !! i | i <- [1,3..(length l) - 1]]

shuffle :: [a] -> [a]
shuffle s   | length s == 1 = s
        | otherwise = l ++ shuffle r
        where l = evens s
              r = odds s

enter image description here

2 个答案:

答案 0 :(得分:2)

完美的随机播放可以实现为

perfectShuffle = concat . transpose . chunksOf 2

速度改进将来自:

  1. 不重复计算列表的长度。
  2. 没有低效地构建(++)链,这将需要重复遍历列表并给出O(n 2 )运行时。
  3. 示例输出:

    λ> perfectShuffle [1..10]
    [1,3,5,7,9,2,4,6,8,10]
    
    chunksOf包中提供了

    splittranspose位于Data.List基础。

答案 1 :(得分:1)

您应该像使用

一样使用!!重复索引到同一列表中
evens l = [l !! i | i <- [0,2..(length l) - 1]]    -- bad

这需要O(n ^ 2)时间,其中n是l的长度,因为l !! i需要O(i)时间。

相反,只需写下这样的内容:

evens [] = []
evens (x:xs) = x : odds xs

odds xs = evens (drop 1 xs)

您的shuffle本身就没问题。