面试题:给定一个函数rand()能产生1到m之间的等概率随机数,产生1到n之间等概率的随机数?
虽然TX的面试已经过去好几天了,然而惨痛的过程还历历在目。人生中第一次正式job面试就这么挂掉了。在于面试官的交流过程中,被问及了几个算法设计题,在今后几篇博文中,我一一总结与诸君分享。
1. 给定一个函数rand()能产生1到m之间的等概率随机数,产生1到n之间等概率的随机数? (为了简化问题,此处m小于n)
当被问到这个问题的时候,LZ我首先的想法就是能不能通过一次Rand就可以把结果找到。然后这个想法就被瞬间推翻了。
那么能否通过多次选取,然后组合呢? 答案是肯定的,然而悲剧的是,当时LZ的脑袋有点混乱了,想到了几个思路都不完备。
这几天冷静下来之后,仔细想了想,现给出一个可行的方案,跟大家讨论讨论。
假设:
已知函数 RandM能够生成[1,m]之间的随机数,满足均匀分布
Rand_mn 在已有RandM的基础上,生成均匀分布的[1,n]之间随机数的函数
m: 已知随机数最大值
n: 目标随机数最大值
PS : 此处约定 m<n && n< m*m
-----------------------------------------
思路:
(1) 通过分别两次生成[1,m]之间的均匀分布的随机数x,y那么 x,y 都属于[1,m],如果要将x和y进行组合的话
其最小覆盖问题变成了
|
z = a*x +y min a 使得z的取值均匀分布 s.t. x属于[1,m] y属于[1,m] |
(2) 由于 x,y 都是在[1,m]之前取值, 所以a能取的最小值为m。
(3) 当a=m时,z的取值范围为 [m+1, m*(m+1)]
若z=z-m, 则z的取值范围就变成了 [1, m*m],并且是均匀分布
(4) 此时,我们的问题就简化成了将[1,m*m]区间的值映射到[1,n]
(5) 采用“舍去法”, 令 re = m*m mod n,可知多余元素的个数
当z的值为(m*m-re, m*m]时,递归进行新的随机数生成,否则进行步骤6
(6) 将[1, m*m -re] 均匀分成n份, 每份的间隔为 gap = (m*m -re)/n;
C++代码实现如下:
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std; int RandM(int m)
{
return rand()%m +;
} /********************************************
* Rand_mn 在已有RandM的基础上,
* 生成均匀分布的[1,n]之间随机数的函数
* m: 已知随机数最大值
* n: 目标随机数最大值
*
* PS : 此处约定 m<n && n< m*m
* -----------------------------------------
* 思路:
* (1) 通过分别两次生成[1,m]之间的均匀分布的随机数x,y
* 那么 x,y 都属于[1,m],如果要将x和y进行组合的话
* 其最小覆盖问题变成了
z = a*x +y
min a 使得z的取值均匀分布
* (2) 由于 x,y 都是在[1,m]之前取值, 所以a能取的最小值
* 为m。
* (3) 当a=m时,z的取值范围为 [m+1, m*(m+1)]
* 若z=z-5, 则z的取值范围就变成了 [1, m*m],并且是均匀分布
* (4) 此时,我们的问题就简化成了将[1,m*m]区间的值映射到[1,n]
* (5) 采用“舍去法”, 令 re = m*m mod n,可知多余元素的个数
当z的值为(m*m-re, m*m]时,递归进行新的随机数生成,否则进行步骤6
* (6) 将[1, m*m -re] 均匀分成n份, 每份的间隔为 gap = (m*m -re)/n;
*********************************************/
int Rand_mn(int m,int n)
{
int rand1 = RandM(m), rand2 = RandM(m);
int temp = m*rand2 + rand1; int re = m*m%n; // 多余个数
int gap =(m*m -re)/n; // 取值间隔 if((m+)*m-re<temp && temp<=m*(m+)) // 需要舍弃的部分
return Rand_mn(m,n);
else
return (temp - m -)/gap +; //返回随机结果
} int main()
{
int m,n;
srand((unsigned )time(NULL));
while(cin>>m>>n)
{
int t=;
while(t--) cout<<Rand_mn(m,n)<<endl;
cout<<endl;
}
return ;
}
面试题:给定一个函数rand()能产生1到m之间的等概率随机数,产生1到n之间等概率的随机数?的更多相关文章
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
题目:给定一个函数rand()能产生1到n之间的等概率随机数,问如何产生1到m之间等概率的随机数? 先把问题特殊化,例如原题变为给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一 ...
- 面试题-->写一个函数,返回一个数组中所有元素被第一个元素除的结果
package com.rui.test; import java.util.Random; /** * @author poseidon * @version 1.0 * @date:2015年10 ...
- 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...
- js数据类型的检测总结,附面试题--封装一个函数,输入任意,输出他的类型
一.javascript 中有几种类型的值 1.基本数据类型 : 包括 Undefined.Null.Boolean.Number.String.Symbol (ES6 新增,表示独一无二的值) 特点 ...
- ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)
1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 154 Solved: 112[ ...
- 用JAVA写一个函数,功能例如以下: 随意给定一组数, 找出随意数相加之后的结果为35(随意设定)的情况
用JAVA写一个函数.功能例如以下:随意给定一组数,比如{12,60,-8,99,15,35,17,18},找出随意数相加之后的结果为35(随意设定)的情况. 能够递归算法来解: package te ...
- 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字
题目:给定一个长度为N的数组,其中每个元素的取值范围都是1到N.判断数组中是否有重复的数字.(原数组不必保留) 方法1.对数组进行排序(快速,堆),然后比较相邻的元素是否相同.时间复杂度为O(nlog ...
- Java笔试题:给定一个ReadOnlyClass的对象roc,能否把这个对象的age值改成30?
在Java笔试面试中,经常会遇到代码题,今天我们就来看一则Java代码笔试题. 有如下代码: Class ReadOnlyClass { private Integer age=20; public ...
- /编写一个函数,要求从给定的向量A中删除元素值在x到y之间的所有元素(向量要求各个元素之间不能有间断), 函数原型为int del(int A ,int n , int x , int y),其中n为输入向量的维数,返回值为删除元素后的维数
/** * @author:(LiberHome) * @date:Created in 2019/2/28 19:39 * @description: * @version:$ */ /* 编写一个 ...
随机推荐
- 一个不明觉厉的貌似包含很多linux资料索引的网页
http://man.lupaworld.com/content/other/Linux/linuxmanage/node108.html 貌似是个官方的doc之类的...
- 可以兼容ie6的纯CSS三级鼠标悬停显示/隐藏菜单实现
本来在chrome上用js写的好好的三级显隐菜单,放到ie6上一测试竟然奇葩般的会瞎闪.问题原因至今没参透,可能是我每次响应事件的处理代码过长??总之我是对ie6幻灭了,去网上搜一搜能支持ie6的下拉 ...
- jQuery之事件和动画
1.加载DOM $(document).ready(function(){ }) 简写形式: $(function(){ }) 事件绑定: 合成事件 事件冒泡 移除事件 JQuery中的动画 show ...
- properties 中文乱码问题的解决
在用properties处理配置信息时,发现有时出现中文乱码的问题,后经查资料得知是由于编码不一致引起的.于是解决之. [原理解释] 我们用 API操作properties文件,如果获取的属性值是中文 ...
- Mysql双机热备实现数据库高可用
mysql双主热备,也称主主互备,目的是mysql数据库高可用,只支持双机,原因是mysql的复制是一主多从,但一个从服务器只能有一个主服务器. 双机热备的条件是双机mysql版本必须一致. 服务器分 ...
- Shaders
[Shaders] 1.Vertex-Lit,顶点光照着色器. Vertex-Lit is one of the simplest shaders. All lights shining on it ...
- [C++] Template Function _ Any number of parameters
Template Function _ Any number of parameters #include<iostream> #include<cstdarg> using ...
- 深入理解yield-乾颐堂
yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法. 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: 1 2 3 def ad ...
- Python Socket实现简单的聊天室
通过参考其他牛人的文章和代码, 再根据自己的理解总结得出, 说明已经加在注释中, FYI 主要参考文章: http://blog.csdn.net/dk_zhe/article/details/3 ...
- 05 Computing GC Content
Problem The GC-content of a DNA string is given by the percentage of symbols in the string that are ...