虽然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之间等概率的随机数?的更多相关文章

  1. 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?

    题目:给定一个函数rand()能产生1到n之间的等概率随机数,问如何产生1到m之间等概率的随机数? 先把问题特殊化,例如原题变为给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一 ...

  2. 面试题-->写一个函数,返回一个数组中所有元素被第一个元素除的结果

    package com.rui.test; import java.util.Random; /** * @author poseidon * @version 1.0 * @date:2015年10 ...

  3. 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。

    谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...

  4. js数据类型的检测总结,附面试题--封装一个函数,输入任意,输出他的类型

    一.javascript 中有几种类型的值 1.基本数据类型 : 包括 Undefined.Null.Boolean.Number.String.Symbol (ES6 新增,表示独一无二的值) 特点 ...

  5. ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)

    1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 112[ ...

  6. 用JAVA写一个函数,功能例如以下: 随意给定一组数, 找出随意数相加之后的结果为35(随意设定)的情况

    用JAVA写一个函数.功能例如以下:随意给定一组数,比如{12,60,-8,99,15,35,17,18},找出随意数相加之后的结果为35(随意设定)的情况. 能够递归算法来解: package te ...

  7. 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字

    题目:给定一个长度为N的数组,其中每个元素的取值范围都是1到N.判断数组中是否有重复的数字.(原数组不必保留) 方法1.对数组进行排序(快速,堆),然后比较相邻的元素是否相同.时间复杂度为O(nlog ...

  8. Java笔试题:给定一个ReadOnlyClass的对象roc,能否把这个对象的age值改成30?

    在Java笔试面试中,经常会遇到代码题,今天我们就来看一则Java代码笔试题. 有如下代码: Class ReadOnlyClass { private Integer age=20; public ...

  9. /编写一个函数,要求从给定的向量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:$ */ /* 编写一个 ...

随机推荐

  1. RTTI(一) 枚举

    SetEnumProp void __fastcall TForm2::Button1Click(TObject *Sender) { //Getting the current color of t ...

  2. 7. H.264的句法和语义

    1.句法 在编码器输出的码流中,数据的基本单位是句法元素,每个句法元素由若干比特组成,它表示某个特定的物理意义,例如:宏块类型.量化参数等. 句法表征句法元素的组织结构,语义阐述句法元素的具体含义. ...

  3. awk 数据处理小技巧

    进行数据分析或统计时,如果数据量较小,我们可以用awk快速处理,以下是一些小技巧   一.时间戳转换 日期转时间戳: date -d "20150315"  "+%s&q ...

  4. centos7 yum 安装 mysql

    CentOS7默认数据库是mariadb,配置等用着不习惯,因此决定改成mysql,但是CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1 ...

  5. 读书笔记 Week7 2018-4-24

    <程序员的自我修养> 首先来大致说一下读这本书的感觉,可以说对于我自己而言,是第一次对于编程有了个纯粹的认识,或者说的更明确一点,是对整个操作系统有了一个大致的感觉.虽然自己这一年也算是写 ...

  6. 104. Maximum Depth of Binary Tree (Tree; DFS)

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. UNITY把3D模型显示在UI层级上的思路

    一般UI是处理于显示最高层级的, 因此这里的做法是 使用镜子效果,做镜子可使用renderTexture 然后启用一个摄像机对renderTexture进行数据填充, 然后在ui上使用Raw Imag ...

  8. Opencv HOG特征检测

    HOGDescriptor hogDescriptor = HOGDescriptor(); hogDescriptor.setSVMDetector(hogDescriptor.getDefault ...

  9. 825. Friends Of Appropriate Ages有效的好友请求的数量

    [抄题]: Some people will make friend requests. The list of their ages is given and ages[i] is the age ...

  10. ansible介绍与安装

    一.什么是ansible ansible是python中一套模块,系统中的一套自动化工具,可以用来作系统管理.自动化命令等任务. 二.ansible优势 .ansible是Python中一套完整的自动 ...