Re: [心得] 樸克牌13支

看板C_and_CPP作者 (死神之藥)時間10年前 (2014/04/19 16:59), 10年前編輯推噓5(504)
留言9則, 3人參與, 最新討論串3/3 (看更多)
爬舊文想說充實一下自己的想法 文章有點舊 (是對於洗牌的寫法) 但對於stonehomelaa版友提出來的第二個方法有點疑問 為什麼被對換的牌是 j = rand() % (52-i); 而不是 j = rand() % (52); 是都可以嗎? 還是這樣做會出現問題? ※ 引述《stonehomelaa (cousin)》之銘言: : ※ 引述《papalun (謎樣人物)》之銘言: : : for (i=0;i<52;i++) : : { : : j=rand()%52; : : temp=A[i]; : : A[i]=A[j]; : : A[j]=temp; : : } : 本來我也認為打亂陣列是這麼做的 : 不過之前看了深度學習C++網站上的試讀章節 : 裡面範例有提到兩種做法 : 其一是陣列元素由後往前與其前的隨機位置對調 : for (i = 52 - 1; i > 0; i--) : { : j = rand() % (i+1); : if(i == j) continue; : temp = A[i]; : A[i] = A[j]; : A[j] = temp; : } ↓這個方法 : 另一個是由前往後與剩餘元素對調,但最後一個不須再對調 : for (i = 0; i < 52 - 1; i++) : { : j = rand() % (52-i); : if(j == 0) continue; : temp = A[i]; : A[i] = A[j]; : A[j] = temp; : } : 而書上說原po的做法會造成錯誤的機率分佈 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.166.75.22 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1397897981.A.904.html ※ 編輯: aqtx4869 (118.166.75.22), 04/19/2014 17:00:15

04/19 17:10, , 1F
Fisher-Yates shuffle 演算法 http://goo.gl/gNiuwb
04/19 17:10, 1F

04/19 17:17, , 2F
發現連結有點弄錯,http://goo.gl/A3oR1x 這個才對
04/19 17:17, 2F

04/19 17:18, , 3F
如果是用 % 52 來做會跟演算法本質不一致,機率會不均勻
04/19 17:18, 3F
所以%52使用上是可行的 但是不符合均勻洗牌的想法 所以才用52-i @@ ※ 編輯: aqtx4869 (118.166.75.22), 04/19/2014 17:37:59

04/19 17:57, , 4F
是的,只是這樣意義就不大了,跟演算法本質就不同 XD
04/19 17:57, 4F

04/19 18:01, , 5F
最簡單的想法是,均勻洗牌有52!種結果,rand()%52 有 52^52
04/19 18:01, 5F

04/19 18:01, , 6F
種「過程」,所以一定不是均勻分佈
04/19 18:01, 6F
了解

04/20 01:48, , 7F
52-i 可以理解成我每次從剩下的牌堆抽一張出來放好
04/20 01:48, 7F

04/20 01:49, , 8F
那個剩下的牌堆的張數就是 52-i
04/20 01:49, 8F
如果是這樣想我會覺得怪怪的 因為先抽出第1張 然後剩51張卻是從"前51張"去挑對換的牌 而不是從"後51張"去挑 rand() % (52-i)+i;

04/20 18:16, , 9F
唔, 仔細看了一下確實如你所說, 要 +i 才是對的
04/20 18:16, 9F
所以我迷糊了@~@ ※ 編輯: aqtx4869 (59.115.81.38), 04/20/2014 19:39:49
文章代碼(AID): #1JKZhza4 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1JKZhza4 (C_and_CPP)