AS3 快速產生不重覆亂數


AS3 快速產生不重覆亂數

看到奶綠文章 FlashAS3 亂數不重復的方法
剛好最近有複習到 AS3 Array 平常少用的 function
所以也來思考怎樣更有效率的產生不重覆亂數
AS3 的 Array 假如單純只有用 Array.NUMERIC 模式排序速度是夠快的
可是一旦用了自定的排序 function,速度就慢上一大截
那要如何利用 Array.NUMERIC 模式排序又能弄亂順序呢?
答案就是改用 sortOn function 來作排序
陣列內的元素改用物件,多一個屬性存放亂數
對亂數欄位作排序就可以了



  1. // 產生 0 到 (n - 1) 不重複亂數陣列
  2. function genRandomArray(n:int):Array {
  3.   var ary:Array = [];
  4.   while (n) ary.push({n: --n, r: Math.random()});
  5.   return ary.sortOn("r"Array.NUMERIC);
  6. }
  7.  
  8. // 產生 0-9999 不重複亂數陣列
  9. var ra:Array = genRandomArray(10000);
  10. trace(ra[0].n); // 取出第一個不重複亂數
  11. trace(ra[1].n); // 取出第二個不重複亂數
這樣就完成了,速度夠快,而且程式碼也相當少
下面是另一種用隨機插入陣列的方式產生不重覆亂數
不過速度比原生的 Array 排序慢一些



  1. // 產生 0 到 (n - 1) 不重複亂數陣列
  2. function genRandomArray(n:int):Array {
  3.   var ary:Array = []; 
  4.   while (n) ary.splice(Math.random() * ary.length, 0, --n);
  5.   return ary;
  6. }
  7.  
  8. // 產生 0-9999 不重複亂數陣列
  9. var ra:Array = genRandomArray(10000);
  10. trace(ra[0]); // 取出第一個不重複亂數
  11. trace(ra[1]); // 取出第二個不重複亂數

當天下午,不斷思考是否還有更快速的方式
結果又有更重大的發現
只要把一堆亂數塞入陣列
然後同時結合 Array.NUMERIC、Array.RETURNINDEXEDARRAY 模式作排序
馬上就拿到不重複的亂數陣列了
在我的 NB 上跑 0-9999 不重複亂數只要 10ms 而已



  1. // 產生 0 到 (n - 1) 不重複亂數陣列
  2. function genRandomArray(n:int):Array {
  3.   var ary:Array = [];
  4.   while (n--) ary.push(Math.random());
  5.   return ary.sort(Array.NUMERIC | Array.RETURNINDEXEDARRAY);
  6. }
  7.  
  8. // 產生 0-9999 不重複亂數陣列
  9. var ra:Array = genRandomArray(10000);
  10. trace(ra[0]); // 取出第一個不重複亂數
  11. trace(ra[1]); // 取出第二個不重複亂數

20110130 補充
後來仔細測試過,以上程式碼很少但不是最快的
假如很要求速度,可能還是得要用 qop奶綠 那種交換陣列元素的方式
但是需要稍微修改一下,不能用 Math.floor 那會降低速度

  1. // 產生 0 到 (n - 1) 不重複亂數陣列
  2. function genRandomArray(n:int):Array {
  3.   var ary:Array = [];
  4.   var i:int, r:int, t:int;
  5.   for (i = 0 ; i < n ; ++i) {
  6.    ary[i] = i;
  7.   }
  8.   for (i = 0 ; i < n ; ++i) {
  9.    r = int(Math.random() * n);
  10.    t = ary[r];
  11.    ary[r] = ary[i];
  12.    ary[i] = t;
  13.   }
  14.   return ary;
  15. }
  16.  
  17. // 產生 0-99999 不重複亂數陣列
  18. var ra:Array = genRandomArray(100000);
  19. trace(ra[0]); // 取出第一個不重複亂數
  20. trace(ra[1]); // 取出第二個不重複亂數


留言

熱門文章