Re: [问题] 从array中随机取得n个不重复元素

楼主: abliou (愚者)   2014-11-03 18:11:28
※ 引述《peter0726 (江 谢)》之铭言:
: 各为版友大家好
: 小弟有个问题,如标题所述
: 现在想写一个功能
: 大致上就是随机从n个数字中取出m个不重复的数字
: 目前写出来的可以正确执行
: 可是当数字大的时候就会执行颇久的
: 想请教各位有没有更有效率的写法0.0?
: 目前的程式码如下
: sub randpick {
: my $max = shift;
: my $need = shift;
: my %pick;
: my @picked = keys %pick;
^^^^^^^^^^^^^^^^^^^^^^^^ 看了半天 不知道这行在干嘛 设定成空阵列?
: while (@picked < $need) {
: my $num = int(rand($max));
: $pick{$num} = 1;
^^^^^^^^^^^^^^^^ 效率不彰的根源就在这
你的"避免重复"的方法就是使用杂凑 但是当你数字多了
抽到一样数字的机会就会变大 造成这个while循环跑不完
解决方法很简单 先做出一个不重复的阵列 把这阵列打乱
然后切前面几个就好了
: @picked = sort{$a <=> $b} (keys %pick);
: }
: return %pick;
: }
sub randpick {
my $max = shift;
my $need = shift;
return @{[sort{rand()>0.5}(0..$max)]}[1..$need];
}
或者连宣告变量都免了
sub randpick {
return @{[sort{rand()>0.5}(0..$_[0])]}[1..$_[1]];
}
作者: xatier (一切重来就好了...)   2014-11-03 19:58:00
推 作法漂亮
作者: CindyLinz (Cindy Wang)   2014-11-03 21:20:00
:D
楼主: abliou (愚者)   2014-11-03 22:19:00
阿 是前辈们不嫌啦....
作者: peter0726 (江 谢)   2014-11-03 22:56:00
请教一下 sort里面的“{rand()>0.5}”是什么意思?我只会sort{$a cmp $b}这样的
作者: CindyLinz (Cindy Wang)   2014-11-03 23:00:00
正常是放两者的比较结果, 现在他说要用电风扇当比较结果, 所以就变成乱排了.. XDrand() 会给一个 [0,1) 之间的随机数
作者: scwg ( )   2014-11-04 00:08:00
还是冒出来说一下, 十年前从兔子那边学到 sort{rand} 的shuffle, 怎么十年来这个又不快, 又不 random 的方法还没死透啊...
作者: CindyLinz (Cindy Wang)   2014-11-04 00:52:00
不过为什么如果写 sort { rand - .5 } 就完全不乱了呢
作者: scwg ( )   2014-11-04 01:03:00
因为 rand - .5 被 parse 成 rand( -.5 ), 回传 -0.5~0怪怪的, 就算 rand() - .5 也不乱
作者: CindyLinz (Cindy Wang)   2014-11-04 01:07:00
可是我写 rand() - .5 也不乱啊 o.o该不会要 -1, 0, 1 吧... orz噢找到了.. perldoc -f sort 的说明里面写:
作者: scwg ( )   2014-11-04 01:08:00
啊, 因为 man page of sort: ... subroutine that returnsan integer less than, equal to, or greater than 0 ...
作者: CindyLinz (Cindy Wang)   2014-11-04 01:09:00
a subroutine that returns an integer less than, equinteger.. QQ
作者: scwg ( )   2014-11-04 01:12:00
不过 { rand > .5 } 还是不算是乱就是了 (fail chi^2 test)
作者: CindyLinz (Cindy Wang)   2014-11-04 01:13:00
嗯, 排 1~10 就感觉得出来了..

Links booklink

Contact Us: admin [ a t ] ucptt.com