Select random element from a set, faster than linear time (Haskell)

前端 未结 8 1638
清酒与你
清酒与你 2021-01-17 11:38

I\'d like to create this function, which selects a random element from a Set:

randElem :: (RandomGen g) => Set a -> g -> (a, g)

Si

8条回答
  •  日久生厌
    2021-01-17 11:54

    As of containers-0.5.2.0 the Data.Set module has an elemAt function, which retrieves values by their zero-based index in the sorted sequence of elements. So it is now trivial to write this function

    import           Control.Monad.Random
    import           Data.Set (Set)
    import qualified Data.Set as Set
    
    randElem :: (MonadRandom m, Ord a) -> Set a -> m (a, Set a)
    randElem xs = do
      n <- getRandomR (0, Set.size xs - 1)
      return (Set.elemAt n xs, Set.deleteAt n xs)
    

    Since both Set.elemAt and Set.deleteAt are O(log n) where n is the number of elements in the set, the entire operation is O(log n)

提交回复
热议问题