Re: [問題] 從array中隨機取得n個不重複元素

作者: CindyLinz (Cindy Wang)   2014-11-03 21:15:17
※ 引述《abliou (愚者)》之銘言:
: 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]];
: }
來幫忙補充一些~ ^^
Perl 的 core module (就是有 perl 就會有, 不用再另外裝的 module)
有一個叫作 List::Util
裡面有個函數叫作 shuffle, 用來把一個 list 打亂
https://metacpan.org/pod/List::Util#shuffle
也蠻適合用在這邊~~
use List::Util qw(shuffle);
sub randpick {
my($max, $need) = @_;
(shuffle (0..$max-1))[0..$need-1];
}
btw, 我覺得這邊的用法還是宣告個變數比較好啦..
因為小括號中括號大括號疊成一大團有點亂.. ^^|
那個 (...)[0..$need-1] 的部分,
這邊也可以考慮 builtin 的 splice, 寫成
use List::Util qw(shuffle);
sub randpick {
my($max, $need) = @_;
splice [shuffle (0..$max-1)], 0, $need;
}
splice 的說明在這邊~~
http://perldoc.perl.org/functions/splice.html
PS.
我這邊 randpick 的最後面沒有寫 return,
這在 Perl 是可以的, 呼叫 randpick() 的人會拿到這最後一個 statement 的結果.
我還不是很肯定這是不是好的風格..
確定的是它會省一個 OP cycle 和無意義的「提前離開」的動作, 效能會比較好
(這是 Perl <= 5.18 的話,
而 Perl >= 5.20 以後會自動把 sub 裡的最後一個 return 去掉)
嗯, 多寫一個 return 字樣, 我原本覺得它當然會比較清楚明確,
只是最近看到 Moz 設計了一套叫作 Rust 的語言
(聽說想用來實作新一代的瀏覽器),
它的定位是效能大約在 C 或 C++ 的層級, 而嚴謹度比它們更好.
在 Rust 裡面如果最後一個 statement 沒有加分號,
那麼呼叫端就會拿到它的結果.
雖然也可以寫成 return,
但是它甚至在官方文件裡面建議不寫 return 為佳...
使我不由得反省我習慣最後面明確寫出 return,
是不是只是從 C 開始就這樣寫,
其後的 C++, Java, 或是 PHP, Javascript 也都一樣,
想要 return 東西出去就一定要寫 return,
其實只是個習慣, 也許不見得是好的習慣..
作者: abliou (愚者)   2014-11-03 22:21:00
splice不錯!!!!!一開始寫perl我也都不用return 接觸C之後才養成習慣
作者: CindyLinz (Cindy Wang)   2014-11-03 22:50:00
到底怎樣比較好咧.. XD
作者: scwg ( )   2014-11-03 23:53:00
當 functional language 寫就不加 return 啦!
作者: CindyLinz (Cindy Wang)   2014-11-04 00:01:00
好像不錯的理由兼藉口.. XD

Links booklink

Contact Us: admin [ a t ] ucptt.com