题目:有一个随机数函数,可以生成1-7的数字,现在要求利用这个函数生成一个1-10的随机数函数。
思路:这道题网络上有各种的解法(可参考 http://blog.csdn.net/zheng0518/article/details/50929826),但是没有给出这道题的没有给出一个最简单的方式,这个最简单的方式,使用的数学模型就是多维数组的访问模型。
比如这道题,1-10这十个数字,我们可以采用2行5列的形式获得,2和5 的随机数可以使用1-7的随机数生成器获得。
代码如下:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <assert.h>
using namespace std;
int Zhongzi()
{
srand(time(NULL));
return 0;
}
int random7()
{
static int nZhongzi = Zhongzi();
return rand() % 7 + 1;
}
int random7_n(int n)
{
if (n > 7 || n < 2) {
assert(0);
return -1;
}
int nYu = 7 % n;
int nNum = random7() - nYu;
while (nNum <= 0) {
nNum = random7() - nYu;
}
return nNum % n + 1;
}
int random10()
{
return (random7_n(2) - 1) * 5 + random7_n(5);
}
int main(int argc, char ** argv)
{
vector<int> vecNum(10, 0);
for (int i=0; i<1000000; ++i) {
int nNum = random10();
vecNum[nNum - 1] += 1;
}
cout << "分布:";
for (auto itr=vecNum.begin(); itr!=vecNum.end(); ++itr)
cout << *itr << " ";
cout << endl;
return 0;
}
上述的random10的函数,我们还可以写random8, random11等等。
random8代码如下:
int random8()
{
return (random7_n(2) - 1) * 4 + (random7_n(2) - 1) * 2 + random7_n(2);
}
random11代码如下(因为11是质数,所以找了一个比11大的最近的一个合数12):
int random12()
{
return (random7_n(3) - 1) * 4 + (random7_n(2)-1) * 2 + random7_n(2);
}
int random11()
{
int nYu = 12 % 11;
int nNum = random12() - nYu;
while (nNum <= 0)
nNum = random12() - nYu;
return nNum % nYu + 1;
}
这里还是加一个注解,说明random12的原理
从右向左说:random7_n(2)表明我现在可以生成{1,2}的随机数,
(random7_n(2)-1) * 2 表明可以生成{0,2}的随机数,加上之后表明可以生成{1,2,3,4}的随机数(可以做个简单的组合{0,1},{0,2},{2,1},{2,2}),同理(random7_n(3) - 1) * 4可以生成{0,4,8}三个随机数,加上之后可以生成{1,2,3,4,5,6,7,8,9,10,11,12}的随机数。
加个注解的原因是,我一下子没有明白为什么!真心佩服我当时的思路!
random11() 的写法还有一种思路,我觉得这个思路应该比我之前写的思路要好
int random11()
{
while (true)
{
int rt = random12();
if (rt <= 11)
{
return rt;
}
}
return 0;
}