虽然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. Shachar Fleishma的论文,做点云重建的几篇论文都不错

    http://www.sci.utah.edu/~shachar/ 几篇论文都不错,但貌似05年之后就没有什么动作了.

  2. AlphaTesting

    [Alpha Testing] The alpha test is a last chance to reject a pixel from being written to the screen. ...

  3. VUE+WebPack实现精美Html5游戏设计:纸牌战争

  4. 前Forward / 延时Deferred

    本章节描述了延时光照的渲染路径的细节,如果想了解延迟光照技术,请查阅Deferred Lighting Approaches article. Deferred Lighting is renderi ...

  5. js中直接对字符串转义-用于solr ulr 关键词转义

    js代码 /* * 获取UTC格式的字符串,参数必须是 */var solrDateFormat = function (o){    var date;    if(typeof o == 'str ...

  6. 使用python进行汉语分词-乾颐堂

    目前我常常使用的分词有结巴分词.NLPIR分词等等 最近是在使用结巴分词,稍微做一下推荐,还是蛮好用的. 一.结巴分词简介 利用结巴分词进行中文分词,基本实现原理有三: 基于Trie树结构实现高效的词 ...

  7. Fix “Could Not Find This Item” When Deleting in Windows 7

    If you’ve been using Windows for as long as I have, you have probably run into your share of weird e ...

  8. [SoapUI] 通过编程的方式设置当前的Environment

    testRunner.testCase.testSuite.project.setActiveEnvironment("Live")

  9. Go语言特性

    1.入口,go有且只有一个入口函数,就是main函数 liteide (IDE)的 一个工程(文件夹)只能有且只有一个main函数 package main import "fmt" ...

  10. C语言cJSON库的使用,解析json数据格式

    C语言cJSON库的使用,解析json数据格式 摘自:https://www.cnblogs.com/piaoyang/p/9274925.html 对于c语言来说是没有字典这样的结构的,所以对于解析 ...