求大神解读下
lua吧
全部回复
仅看楼主
level 2
-- 等概率随机排列数组
function g_fn_shuffle( arr )
if arr == nil then
return
elseif #arr <= 1 then
return
end
for i=#arr,1,-1 do
local j = math.random(i)
local value = arr[i]
arr[i] = arr[j]
arr[j] = value
end
end
------------------
2014年06月21日 18点06分 1
level 2
的 ,
2014年06月21日 18点06分 2
level 13
这个函数的作用就是把一个表随机打乱,通俗地说就是“洗牌程序”。
但是这个短短的十多行的小程序,却有一个严重算法错误,以及几个可以吐槽的地方,可以看出作者编程经验欠缺,lua也不熟悉。
2014年06月22日 05点06分 3
level 13
也说一下算法错误,算法本意是用循环顺序将每一张牌和一个随机的牌交换位置,以达到洗牌的目的。作者可能想将已经处理过的位置不再被随机,但是这种算法首先不符合实际,大家想一下实际洗牌的时候你会去刻意保证洗过的牌不再改变位置吗?其次,越到后面的牌可以随机的位置越少,而到了第一张牌(作者用的倒序),random的范围也是1,根本没得选,位置根本不会变。
所以,这个算法应该改成:无论哪张牌,可以随机的位置都是整副牌。
2014年06月22日 05点06分 4
度娘吞链接 这里的算法是正确的 自行wiki : Fisher–Yates shuffle
2014年06月23日 16点06分
level 13
再说说可以吐槽的地方。
首先:第一个if语句,是判断表为空返回;而第二个elseif,是判断表项数<=1返回。第二个判断完全包容了第一个判断,因此第一个判断是不需要的。
其次:交换两个数组元素,作者的写法在任何语言中都是对的,但是在lua中有更简明的方法: a,b = b,a ,这样就简单交换了两个变量的值。
2014年06月22日 05点06分 5
#作用于nil值是会出错的。正确的判断应该是: if type(arr) ~= 'table' or #arr <= 1 then return end
2014年06月23日 02点06分
回复 ks_isaf :回复 ks_isaf :嗯,你说得对,不过自己用的函数真心没必要判断那么严格了,主要是防运行中的错误。因为游戏中由于出牌等原因,经常会做table.remove(),导致表变成空表,基于这个理由防出错判断一下即可。如果参数类型都搞错,程序直接就错了,不会有运行中错误。
2014年06月23日 14点06分
level 13
程序改写如下:
function g_fn_shuffle( arr )
if #arr <= 1 then return end
for i=1,#arr do
local j = math.random(#arr)
arr[i],arr[j] = arr[j],arr[i]
end
end
2014年06月22日 05点06分 6
level 13
好吧,被打脸了,首先承认自己孤陋寡闻。
wiki了一下,发现这是一个改进过的fisher kate shuffle算法:
The modern version of the Fisher–Yates shuffle, designed for computer use, was introduced by Richard Durstenfeld...
算法描述如下:
这确实是一个完美的、绝对等概率的洗牌算法。不过现实中不存在完美的洗牌,而且洗得越均匀越不容易出“大牌”,所以自己写应用是否要照抄需要权衡一下。
后头观察一下算法描述,它是0到n-1的数组(c语言表述法,下标从0开始),下行到1为止。转换为lua语言,应该是从#arr到2为止,而不是1。
所以,我依然要鄙视楼主的这个程序,抄都抄错!
最后@霞虫
2014年06月23日 23点06分 8
总不会算错 上面的算法downto 0结果也是正确的 只是多了一项冗余操作 至于楼主给出的算法则是错误的 对于原序列的某一位 shuffle后出现在序列各位置的概率不总是相同的
2014年06月24日 05点06分
回复 即使此翼不折 :第一,我说过我要等概率随机数列么?我一再说等概率算法在实际应用中并不见得是好的算法。第二,你说我算法错误,概率不同,请论证不同在何处,那一位的概率高了或低了?第三,给你一副牌,用两种算法去洗牌,你能区分出结果是哪种算法算出来的么?
2014年06月24日 15点06分
回复 沙城雨人 : http://ideone.com/iH2h74
2014年06月24日 16点06分
回复 即使此翼不折 :实证说明lz_shuffle(我不是楼主哈[滑稽])确实比fy_shuffle波动大,从算法角度来说肯定是经典的FY算法完美。拜服ozn...
2014年06月25日 03点06分
1