电脑爱好者之家

Javascript(洗牌算法)二

时间:2012-10-22 22:41来源:未知 作者:熊猫蜀黍 点击:
接之前的文章 《JavaScript(洗牌算法)随机打乱数组元素的位置》 http://www.chinambs.com/a/jiaobensheji/2012/1022/53.html 或许经过测试你会发现:有一些元素在洗完牌后位置依然是原来的位置,而且出现这种元素的几率很大。那怎么改进呢? 在现实当中,

接之前的文章

《JavaScript(洗牌算法)随机打乱数组元素的位置》
http://www.chinambs.com/a/jiaobensheji/2012/1022/53.html

或许经过测试你会发现:有一些元素在洗完牌后位置依然是原来的位置,而且出现这种元素的几率很大。那怎么改进呢?

在现实当中,我们洗完牌后,通常还会把扑克一分为二(俗称“切牌”),然后交换这两部分的上下位置。嗯,对,这个洗牌函数里我们没有切牌!

所以我们可以做如下改进:

 

[javascript] view plaincopyprint?
  1. //洗牌算法   
  2. function mess(arr){  
  3.     var _floor = Math.floor, _random = Math.random,  
  4.         len = arr.length, i, j, arri,  
  5.         n = _floor(len/2)+1;  
  6.     while( n-- ){  
  7.         i = _floor(_random()*len);  
  8.         j = _floor(_random()*len);  
  9.         if( i!==j ){  
  10.             arri = arr[i];  
  11.             arr[i] = arr[j];  
  12.             arr[j] = arri;  
  13.         }  
  14.     }  
  15.     //增加切牌操作   
  16.     i = _floor(_random()*len);  
  17.     arr.push.apply(arr, arr.splice(0,i));  
  18.     //return arr; //要不要返回打乱后的数组呢?   
  19. }  
  20. var testa = [1, 2, 3, 4, 5, 6, 7, 8, 9];  
  21. var newarr = testa.slice(0);  
  22. mess(newarr);  
  23. console.log(testa);  
  24. console.log(newarr);  
好,现在看来,已经很少出现洗牌前后位置不变的元素了,可以说大功告成了。

 

巴特,稍等,我们已经发现,这个洗牌函数是会改变原始数组的,那么,接下来有一个问题:这个函数要不要返回值,返回打乱后的数组?因为我可能想这么来调用它:

[javascript] view plaincopyprint?
  1. var testa = [1, 2, 3, 4, 5, 6, 7];  
  2. var newarr = mess( testa.slice(0) ); //这里只是浅拷贝数组  
这种调用方式好吗?如果加上这种调用方式,那么可以算一共有两种调用方式。

 

其实,对这么一个简单函数而言,调用方法应该越简单越好,简单易用,最好只提供一种调用方式。使用方法多了就需要人多记东西,容易让人迷糊。所以,我不想给这个洗牌函数返回值,不想提供这种调用方式。
而且还有一个原因:这有利于强调这是一个改变原数组的函数,而不是通过返回值来给出调用结果,这样可以让调用者明确知道调用函数的影响。

(责任编辑:熊猫蜀黍)
织梦二维码生成器
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片