随机数生成器

题目:有一个随机数函数,可以生成1-7的数字,现在要求利用这个函数生成一个1-10的随机数函数。
思路:这道题网络上有各种的解法(可参考 http://blog.csdn.net/zheng0518/article/details/50929826),但是没有给出这道题的没有给出一个最简单的方式,这个最简单的方式,使用的数学模型就是多维数组的访问模型。
比如这道题,1-10这十个数字,我们可以采用2行5列的形式获得,2和5 的随机数可以使用1-7的随机数生成器获得。
代码如下:

#include 
#include 
#include 
#include 
#include 
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 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;
}

你可能感兴趣的:(随机数生成器)