區間數值隨機

1 題目

給定一個從0到N的閉區間,隨機地輸出該區間內的整數,每個整數出現且僅出現一次。

2 思路1

直接通過內置的隨機函數,每次隨機出一個值,然後放入到列表中

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func getRandIntList(length int) []int {
	var intList []int
	numberExistMap := map[int]bool{}
	rand.Seed(time.Now().Unix())
	for true {
		// 返回[0, length)內的隨機值
		randNumber := rand.Intn(length)
		if _, ok := numberExistMap[randNumber]; ok {
			continue
		}
		numberExistMap[randNumber] = true
		intList = append(intList, randNumber)
		if len(intList) == length {
			break
		}
	}

	return intList
}

func main() {
	intList := getRandIntList(10)
	fmt.Println(fmt.Sprintf("intList:%+v with length:%d", intList, len(intList)))
}

輸出:

intList:[3 4 2 7 8 1 9 5 6 0] with length:10

這種方法其實並沒有滿足每個數字只出現一次的要求。

3 思路2 - 素數取模隨機法

  • 對於一個數組[n]int,隨機的從小於n的素數集合中,選擇一個素數,假定是p;
  • 從數組[0, n-1]中隨機選擇一個數開始,假定是m;
  • 隨機出來的第一個值爲(m + p) % n = i,第二次值爲(上一個值 + p) % n,也就是(i+p) % n,以此類推,就產生了n個數,;

舉例:對於[1, 8]的區間,其素數集合是{1, 3, 5, 7},假定選擇的素數是5,從1開始。

訪問輪次 取模值 所需值
1 (1 + 5)%8 = 6 6 + 1 = 7
2 (6 + 5)%8 = 3 3 + 1 = 4
3 (3 + 5)%8 = 0 0 + 1 = 1
4 (0 + 5)%8 = 5 5 + 1 = 6
5 (5 + 5)%8 = 2 2 + 1 = 3
6 (2 + 5)%8 = 7 7 + 1 = 8
7 (7 + 5)%8 = 4 4 + 1 = 5
8 (4 + 5)%8 = 1 1 + 1 = 2

從上面例子可以看出,執行8次即可產生全部的元素,而且由於素數和開始的數是隨機的,那麼結果也能做到隨機性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章