Erlang练习:洗牌算法——将一个序列打乱,类似于Python里面的shuffle函数。

问题的来源:

问题描述:假设有一个数组,包含n个元素。现在要重新排列这些元素,要求每个元素被放到任何一个位置的概率都相等(即1/n),并且直接在数组上重排(in place),不要生成新的数组。用 O(n) 时间、O(1) 辅助空间。


算法的证明:

来计算一下概率。如果某个元素被放入第i( 1in )个位置,就必须是在前 i - 1 次选取中都没有选到它,并且第 i 次选取是恰好选中它。其概率为:

pi=n1n×n2n1××ni+1ni+2×1ni+1=1n

可见任何元素出现在任何位置的概率都是相等的。


网上的资源:

http://www.gocalf.com/blog/shuffle-algo.html

http://coolshell.cn/articles/8593.html


Fisher_Yates算法的Erlang实现:

-module(shuffle).

-compile(export_all).

shuffle(L) ->
    shuffle(list_to_tuple(L), length(L)).

shuffle(T, 0)->
    tuple_to_list(T);
shuffle(T, Len)->
    Rand = random:uniform(Len),
    A = element(Len, T),
    B = element(Rand, T),
    T1 = setelement(Len, T,  B),
    T2 = setelement(Rand,  T1, A),
    shuffle(T2, Len - 1).
    
main()->
    shuffle(lists:seq(1, 10)).

不足:Erlang里面对lists处理的函数有些不足,没有对下标为i的元素进行操作的函数,所以就将其转换为tuple进行处理了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值