如题
怎么实现一个方法,实现传入值后,等概率输出0或1,(0和1每个概率都是50%)
怎么根据f(x)实现一个f1(x) ,要求f1(x)满足,传入参数后,等概率输出0-9,(0-9每个概率都是10%)
附上灵魂图片
如题
怎么实现一个方法,实现传入值后,等概率输出0或1,(0和1每个概率都是50%)
怎么根据f(x)实现一个f1(x) ,要求f1(x)满足,传入参数后,等概率输出0-9,(0-9每个概率都是10%)
附上灵魂图片
参考资料
https://www.geeksforgeeks.org...
https://leetcode-cn.com/probl...
程序员面试金典第六版16.23
const uniform = (a: number, b: number): number => {
return a + Math.floor((b - a) * Math.random())
}
const rand2 = () => {
return uniform(0, 2)
}
const rand4 = () => {
return 2 * rand2() + rand2()
}
const rand10 = () => {
const ans = 4 * rand4() + rand4()
if (ans < 10) return ans
return rand10()
}
const map = {
0: 0,
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0,
7: 0,
8: 0,
9: 0,
10: 0,
}
for (let i = 0; i < 1e6; ++i) {
++map[rand10()]
}
console.log(map)
由于题主未指明传参的用途,以下仅回答2个随机取数部分
Math.floor(Math.random()*2); // 获取 0 到 1 的随机整数。
Math.floor(Math.random()*10); // 获取 0 到 9 的随机整数。
这里使用round与toFixed其实是不符合等概率的。
从楼主后面的回复,如果需要满足限定次数下必随机到,可以通过随机后移除已随机到的部分继续随机以满足
需要额外指出的是函数的定义与注释需要表达语义,代码误用或理解错误很多就是语义不清晰造成的,好比楼主的等概率与大家的回答。
-------------分割线-------------------------------------------
另单指小天的答案,
f(min,max),使用的人大概率会认为该函数是随机[min, max],我说的错就是这个,其他的什么round,等分概率全是他自己捏出来的靶子在那攻击,满嘴喷那啥,一口一个上等人阴阳怪气,还在那摆什么资历,笑死个人,素质高下一眼立见。指出他错误,估计是被别人踩了答案以为是我,结果乱骂一通!建议大家举报一下
等下 人家题意应该是要用50%的概率搞出个10%吧 类似
function pten() {
return f() * f() * f();
}
function random() {
for(let i = 0; i <= 9; i++) {
if (pten()) {
return i;
}
}
return 9
}
这样吧?
只是这个10%不知道怎么搞出来?
从你描述来看,其实与传入的参数没有任何关系~应该是一个有固定规则输出的纯函数。
这是一个常见简易转盘抽奖概率设计。
按照你的问题,假设有如下靶子:
由你投掷飞镖,对于左边的靶子,0区域与1区域平分靶子面积,那么你每次投掷命中 0 ,1区域的概率都是50%;
抽象成纯函数:
function f() {
return Math.floor(Math.random()*2)
}
对于右边的靶子,0-9 10个区域平分靶子面积,那么你每次投掷,命中其中一个区域的概率都是10%。
抽象成纯函数:
function f() {
return Math.floor(Math.random()*10)
}
因为[0-0.1)*10 =0 (取最小整数)
因为[0.1-0.2)*10 =1 (取最小整数)
以此类推,每个区域恰好命中同样的数值区间。
当然,因为Math.random()
返回一个浮点伪随机数在范围[0,1),(包括0,但是不包括1)导致命中最大值的概率(第一个是1,第二个是9)会稍微有误差,但也会无限接近50% 或10%.
希望能解答你的问题。
------------- 我是分割线 -------
仅仅是传参然后依次输出0-9的话,更简单了:
(
function (window){
window.result = -1
function f(anyVal) {
if (window.result === 9) {
window.result = -1
}
window.result +=1
return window.result
}
window.f=f
}
)(window)
结果如图:
随便怎么输入,就考察一个值的存储,为了显得基础扎实点,你可以将window.result
换成闭包。
这样还不行的话。。。你可以反问面试官了
------- 分割线2 -----
有一部分审题没严谨,做出了不严谨的回答,给题主道歉。题中有提到需要利用f(x),我重新补充下:
(
function (window){
window.result = -1
function f1(x) {
if(f(x)){ //只有f(x)等概率输出1时才允许 f1(x)返回有意义的值,这样保证每个f1(x)计算出来的值都是基于f(x)等概率输出一次1的概率
if (window.result === 9) {
window.result = -1
}
window.result +=1
return window.result
}
}
window.f1=f1
}
)(window)
根据已采纳的层主解释,将php转化为js,自己写了一个,感谢层主@kumfo
function f(x:number):number{
return mt_rand(0, 1)
}
function f1(x:number):number {
let n = 0
n += 0x1*fx(x)
n += 0x10*fx(x)
n += 0x100*fx(x)
n += 0x1000*fx(x)
if (n > 9) {
return f1(x)
}else{
return n
}
}
(可以设定传值,但没必要)
// f() 等概率返回 0 或 1
int f();
// f1() 等概率返回 0 - 9 中任意数字
int f1() {
int t = f() | f() << 1 | f() << 2 | f() << 3;
return t <= 9 ? t : f1();
}
9 回答9.5k 阅读
6 回答5.1k 阅读✓ 已解决
5 回答3.7k 阅读✓ 已解决
3 回答10.5k 阅读✓ 已解决
4 回答8k 阅读✓ 已解决
7 回答10.1k 阅读
4 回答7.4k 阅读
这题是个数学题啊,看到各位都在吵架,首先,数学上的定义是:
两个事件发生的概率相乘 = 两件事同时发生的概率
所以,从数学上来说,如果
A事件
发生的概率是50%
,B事件
发生的概率也是50%
,那么A和B
同时发生的概率为:50%*50%=25%
从题目这里来看,有个已知条件,或者叫做已知函数
f(x)
,在已知条件上写一个新的函数f1(x)
,而题目的条件是等概率输出0~9
,所以相当于基于50%
概率发生器创建一个10%
的概率发生器。怎么创建一个10%的事件发生器呢,我们从公式可知,
f(x)
产生事件概率P(1)=50%
,P(0)=50%
,那么P(1)
两次执行,也就是两次结果都是1的概率为25%
,三次结果都是1的概率为12.5%
,四次执行都为1的概率为6.25%
,相当于四次产生的1111
组合的概率为6.25%
,也就是1/16
.这个数据是不是很熟悉?我们用程序生成一下四次0和1产生的组合数:
这个数据是不是很熟悉?相当熟悉,就是个二进制数,转换成十进制之后,就是0~15,相当于16个数每个数发生的概率都是1/16;从另外一个角度来说,从0到16发生的概率都相等,那么也就是说,从0~9数据产生的概率都相等。那么这个
f1(x)
应该就是在其中调用4次f(x)
,生成4位的二进制数,然后再转换成10进制数,如果这个数大于9
,再重新生成即可。自然也就实现了等概率生成0~9的数据。
以下是PHP语言的实现,其他语言实现我就懒得写了: