Golang洗牌演算法
阿新 • • 發佈:2018-12-19
兩種洗牌演算法: 1、Fisher-Yates 2、Knuth
type Handle struct {
}
Fisher–Yates 洗牌演算法
// Fisher-Yates正向 func (h *Handle) shuffle_FisherYates_Forward(cards []uint32, r *rand.Rand) { var size int = len(cards) var j int = 0 for i, _ := range cards { j = r.Intn(size-i) + i cards[i], cards[j] = cards[j], cards[i] } } // Fisher-Yates反向 func (h *Handle) shuffle_FisherYates_Reverse(cards []uint32, r *rand.Rand) { var size int = len(cards) var j int = 0 for i := size - 1; i > 0; i-- { j = r.Intn(i + 1) cards[i], cards[j] = cards[j], cards[i] } }
Knuth洗牌演算法
// 第一步:為每張牌生成一個隨機數 // 第二步:按這個隨機數進行排序 type Knuth struct { index int ran int } func (h *Handle) shuffle_Knuth(cards []uint32, r *rand.Rand){ l := len(cards) tmp := make([]uint32, l) rands := make([]Knuth, l) for i := 0; i < l; i++{ rands[i] = Knuth{index:i, ran:r.Intn(l)} tmp[i] = cards[i] } BubbleSort(rands) for i,v := range rands{ cards[i] = tmp[v.index] } } // 氣泡排序 func BubbleSort(arr []Knuth) []Knuth { num := len(arr) for i := 0; i < num; i++ { status := false for j := i + 1; j < num; j++ { if arr[i].ran > arr[j].ran { status = true arr[i], arr[j] = arr[j], arr[i] } } if status == false { break } } return arr }
入參解釋
1、cards []uint32 // 即將要洗的牌 2、r *rand.Rand // 隨機方式 生成方式:var r *rand.Rand = rand.New(rand.NewSource(“一個64位的隨機種子”) 隨機種子的選擇建議:由於實際情況下,多機器執行速率很快,可能導致併發的時候,生成的納秒種子可能多次相同。所以建議種子由snowflake演算法生成唯一性。
個人眼界有限,如果有什麼好的洗牌演算法,希望大家留言~~