【发布时间】:2014-12-02 08:09:29
【问题描述】:
如何轻松地打乱 sml 中的元组列表?似乎没有任何内置功能可以这样做。
我假设我需要使用随机数生成器,但我不知道如何移动列表中的项目。
【问题讨论】:
标签: list random sml shuffle smlnj
如何轻松地打乱 sml 中的元组列表?似乎没有任何内置功能可以这样做。
我假设我需要使用随机数生成器,但我不知道如何移动列表中的项目。
【问题讨论】:
标签: list random sml shuffle smlnj
这是给Moscow ML's Random library的。对于SML/NJ's Random library,你需要稍微调整一下随机函数。
val _ = load "Random"
val rng = Random.newgen ()
(* select([5,6,7,8,9], 2) = (7, [5,6,8,9]) *)
fun select (y::xs, 0) = (y, xs)
| select (x::xs, i) = let val (y, xs') = select (xs, i-1) in (y, x::xs') end
| select (_, i) = raise Fail ("Short by " ^ Int.toString i ^ " elements.")
(* Recreates a list in random order by removing elements in random positions *)
fun shuffle xs =
let fun rtake [] _ = []
| rtake ys max =
let val (y, ys') = select (ys, Random.range (0, max) rng)
in y :: rtake ys' (max-1)
end
in rtake xs (length xs) end
【讨论】:
select(xs, i)。当Random.range (0, max) rng 被调用时,它会在区间 [0,max) 中生成一个值(即不计算 max 本身)。 SML/NJ 的 Random.randRange 使用包含区间,这意味着您需要从最大值中减去 1:Random.randRange (0, max-1) rng。否则,随机数生成器会偶尔生成一个太大的数字。