Go的两种不重复随机实现

第一种,使用 rand.Perm,但是会稍微浪费一点内存,如果 randomElementsCount << len(array) 那就不太合适

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

func getRandomElements(array []int, randomElementsCount int) []int{

ii := rand.Perm(len(array))

for k, i := range ii[:randomElementsCount] {

result[k] = array[i]

}



return result

}

第二种,常见的生成方法,但是如果randomElementsCountlen(array)差距很小,那么时间上将会很窒息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

func getRandomElements(array []int, randomElementsCount int) []int{

result := make([]int, randomElementsCount)

existingIndexes := make(map[int]struct{}, 0)

for i := 0; i < randomElementsCount; i++ {

randomIndex := randomIndex(len(array), existingIndexes)

result[i] = array[randomIndex]

}



return result

}

func randomIndex(size int, existingIndexes map[int]struct{}) int {

rand.Seed(time.Now().UnixNano())

for {

randomIndex := rand.Intn(size)

_, exists := existingIndexes[randomIndex]

if !exists {

existingIndexes[randomIndex] = struct{}{}

return randomIndex

}

}

}


Go的两种不重复随机实现
https://hunsh.net/archives/112/
发布于
2021年3月25日
许可协议