1. 程式人生 > >Golang洗牌演算法

Golang洗牌演算法

兩種洗牌演算法: 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演算法生成唯一性。

個人眼界有限,如果有什麼好的洗牌演算法,希望大家留言~~