rand1 生成 rand9

2022-09-08 20:12:42 浏览数 (1)

文章目录

  • 1.问题描述
  • 2.难度级别
  • 3.解决思路
  • 4.实现示例
  • 参考文献

1.问题描述

这是一道我于 20220706 周三上午于深圳科兴科学园 D1 参与富图社招二面遇到的算法题。

给定一个函数 rand1 会 50% 的概率输出 0 和 1,请利用 rand1 实现 rand9,等概率地输出 0~9 这 10 个数字。

2.难度级别

难度应该是 middle。

3.解决思路

从题目来看,有个已知条件,rand1() 会 50% 的概率输出 0 和 1,在已知条件的基础上实现一个新的函数 rand9(),所以相当于基于 50% 概率发生器创建一个 10% 的概率发生器。

怎么创建一个 10% 的事件发生器呢,我们从公式可知,rand1 产生事件概率 P(0)=50%,P(1)=50%,那么 rand1 执行两次,也就是两次结果都是 1 的概率为 25%,三次结果都是 1 的概率为 12.5%,四次执行都为1的概率为 6.25%,相当于四次产生的 1111 组合的概率为6.25%,也就是 1/16。

这个数据是不是很熟悉?我们用程序生成一下四次 0 和 1 产生的组合数:

代码语言:javascript复制
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

就是个二进制数,转换成十进制之后,就是0~15,相当于 16 个数每个数发生的概率都是 1/16;也就是说,产生 0 到 9 的概率是相等的,虽然概率不是 1/10。

所以该问题解法是拒绝采样法:调用 4 次 rand1,生成 4 位的二进制数,然后再转换成 10 进制数,如果这个数大于 9,再重新生成即可

4.实现示例

下面使用 Golang 给出实现示例。

首先我们实现 rand1。

代码语言:javascript复制
package main

import (
	"math/rand"
)

// rand1 等概率输出 0 和 1。
func rand1() int {
	return rand.Intn(2)
}

再根据 rand1 实现 rand9:

代码语言:javascript复制
// rand9 等概率输出 0 ~ 9。
func rand9() int {
	for {
		n := rand1()<<3   rand1()<<2   rand1()<<1   rand1()
		if n < 10 {
			return n
		}
	}
}

rand9 输出示例:

代码语言:javascript复制
1
4
8
6
9
3
2
2
8
5

参考文献

已知f(x) 传入的值 等概率 输出0 or 1,如果写一个f1(x)实现等概率输出0-9?| segmentfault 用 Rand7() 实现 Rand10() | LeetCode

ode

0 人点赞