抽奖问题分析
时间:2022-05-06
本文章向大家介绍抽奖问题分析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
用户随机抽奖,数据如下:
// map中,key代表用户名,value代表成用户下单数
var users map[string]int64 = map[string]int64{
"a": 10,
"b": 6,
"c": 3,
"d": 12,
"f": 1,
}
思路
随机问题,一般就是通过随机函数从某个范围内随机取出某个数值,则该数值对应的就是中奖用户
在这里,如果我们能给map中每个元素设置对应的索引,即转化为数组,是不是就可以解决问题了呢?
代码实现
func GetAwardUserName(users map[string]int64) (name string) {
size := len(users)
awardIndex := rand.Intn(size)
i := 0
for userName, _ := range users {
if i == awardIndex {
name = userName
return
}
i++
}
return
}
单元测试
func Test_GetAwardUserName(t *testing.T) {
var users map[string]int64 = map[string]int64{
"a": 10,
"b": 6,
"c": 3,
"d": 12,
"f": 1,
}
rand.Seed(time.Now().Unix())
awardCount := make(map[string]int)
for i := 0; i <= 1000000; i++ {
awardName := GetAwardUserName(users)
if count, ok := awardCount[awardName]; ok {
awardCount[awardName] = count + 1
} else {
awardCount[awardName] = 0
}
}
for n, c := range awardCount {
fmt.Printf("%v:%vn",n,c)
}
}
测试结果:
为了验证获奖概率的正确性,循环执行100万次,每个用户获奖的次数基本在20万左右,每个用户的获奖概率相等
c:200102
f:199853
b:198942
a:200395
d:200704
权重抽奖问题描述:
数据结构和上面抽奖问题一致,只是这里,要求中奖概率和用户的订单数成正比
思路
==本质==还是随机函数获得一个数值,数值对应的用户即获奖用户;这里要实现订单数对获奖概率的影响问题,即==订单数对应随机数的某个范围,订单数越大,范围越大,随机数落在范围内的概率越大==
代码实现
func getAwardUser_weight(users map[string]int64) (name string) {
type awardUser struct {
name string
offset int64
count int64
}
userSli := make([]*awardUser, 0,len(users))
var sumCount int64 = 0
for n, c := range users {
a := awardUser{
name: n,
offset: sumCount,
count: c,
}
//整理所有用户的count数据为数轴
userSli = append(userSli, &a)
sumCount += c
}
awardIndex := rand.Int63n(sumCount)
for _, u := range userSli {
//判断获奖index落在那个用户区间内
if u.offset+u.count>awardIndex {
name = u.name
return
}
}
return
}
单元测试
func Test_getAwardUser_weight(t *testing.T) {
var users map[string]int64 = map[string]int64{
"a": 10,
"b": 6,
"c": 3,
"d": 12,
"f": 1,
}
rand.Seed(time.Now().Unix())
awardCount := make(map[string]int)
for i := 0; i <= 100000; i++ {
awardName := getAwardUser_weight(users)
if count, ok := awardCount[awardName]; ok {
awardCount[awardName] = count + 1
} else {
awardCount[awardName] = 0
}
}
for n,c := range awardCount {
fmt.Printf("%v:%v n",n,c)
}
}
测试结果:
循环遍历了100万次,获奖的次数,与用户的订单数成正比
c:93479
f:31206
d:375614
b:186933
a:312764
总结
解决实际问题,往往都有数学模型去对应,比如抽奖问题,就可以转化为初中所学习的数轴知识,画个草图,简单易理解,也不需要多高深的数学知识
问题本身并不难,重要的是转换思路,将抽象问题简化为具体的数学问题,然后去解决
- ONOS 实战分享(一):项目建立、调试到热部署
- 自己动手系列-延迟队列
- OVS中Action源码分析&自定义Action
- 读懂一行Full GC日志(回复JVM内存分配担保机制一文中 Mr/Mrs Xxx 在留言区提出的问题)
- 总结了一些指针易出错的常见问题(四)
- 当你在浏览器中输入Google.com并且按下回车之后发生了什么?
- 总结了一些指针易出错的常见问题(三)
- C++/C头文件 .h和 .c
- 史上最清晰的红黑树讲解(下)
- 网络操作系统VyOS安装与初步使用
- 为何webpack风靡全球?三大主流模块打包工具对比
- 今天研究了一下手机通信录管理系统(C语言)
- Android软件测试Monkey测试工具
- 程序员面试50题(4)—把字符串转换成整数[算法]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一个有趣的例子带你入门canvas
- GitLab 12 跨版本 13 升级
- 【Rust日报】2020-07-28 SO:在命令行下浏览StackOverflow
- 【翻译】200行代码讲透RUST FUTURES (6)
- MPU6050姿态解算方式1-DMP
- 打卡群刷题总结0729——分隔链表
- 单细胞tSNE细胞降维图还可以这样做?!
- 从IIC实测波形入手,搞懂IIC通信
- FreeRTOS例程4-串口DMA收发不定长数据
- FreeRTOS例程3-串口中断接收不定长的数据与二值信号量的使用
- 前端如何将json数据导出为excel文件
- 使用Postman访问腾讯云API3.0
- C语言将float拆分为4个hex传输与重组
- C语言字符串相关函数使用示例 strtok_r strstr strtok atoi
- FreeRTOS例程1-基础任务创建