package main
import (
"fmt"
"math/rand"
)
func main() {
mpWeight := map[int32]int32{
1: 1, 2: 4, 4: 16, 8: 64,
}
mpRet := make(map[int32]int32, 0)
for i := int32(0); i <= 1000; i++ {
mpRet[RandomForWeight(mpWeight)]++
}
fmt.Println(mpRet)
}
func RandomForWeight(mpWeight map[int32]int32) int32 {
if len(mpWeight) <= 0 {
fmt.Println("param rewardCache not null")
return 0
}
return RandomForWeightSub(RandomForWeightTmp(mpWeight))
}
func RandomForWeightTmp(rewardCache map[int32]int32) (sum int32, totals, key []int32) {
sum = int32(0)
totals = make([]int32, 0)
key = make([]int32, 0)
for k, v := range rewardCache {
if v <= 0 {
continue
}
sum += v
totals = append(totals, sum)
key = append(key, k)
}
return
}
func RandomForWeightSub(sum int32, totals, key []int32) int32 {
if sum <= 0 {
return 0
}
n := RandBetween(1, sum)
mid, distance := int32(0), int32(0)
low, high := int32(0), int32(len(totals))
for low < high {
mid = (low + high) / 2
distance = totals[mid]
if distance < n {
low = mid +1
} else if distance > n {
high = mid
} else {
low = mid
break
}
}
return key[low]
}
func RandBetween(b1, b2 int32) int32 {
if b1 == b2 {
return b1
}
min, max := int64(b1), int64(b2)
if min > max {
min, max = max, min
}
return int32(rand.Int63n(max-min+1) + min)
}
运用结果
ChatGPT版本
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
type Prize struct {
name string
weight int
}
func main() {
prizes := []Prize{
{"iPhone", 30},
{"iPad", 20},
{"MacBook", 50},
}
rand.Seed(time.Now().UnixNano())
totalWeight := 0
for _, prize := range prizes {
totalWeight += prize.weight
}
r := rand.Intn(totalWeight)
var selectedPrize Prize
for _, prize := range prizes {
if r < prize.weight {
selectedPrize = prize
break
}
r -= prize.weight
}
fmt.Println("恭喜您,获得了:", selectedPrize.name)
}
在上面的代码中,我们首先定义了一个奖品结构体Prize,其中name字段表示奖品名称,weight字段表示奖品的权重。
然后,我们通过计算奖品的总权重,生成一个随机数,再遍历奖品,依次减去每个奖品的权重,直到随机数小于当前奖品的权重,那么就说明当前奖品被选中了。
注意:这仅是一种实现方式,其他实现方式也可能存在。