数据结构算法面试题精选及整理-随机数rand7生成rand10函数

据说来自百度的一个面试题

问题其实很简单:

就是一个函数rand7()可以生成1~7的随机数,现在要求用这个随机数生成器来生成rand10()函数。

条件是:不能用循环或递归


点击打开链接里面有讨论。这里要感谢一下这个好学的同学。整理了一下,我就不再整理了。

不过这里可以提供我的思路

大致方法如下:

首先需要生成[1 2]上的随机函数_rand2()。

然后再生成[1 ,2 ,3, 4, 5]上的随机函数_rand5()。

然后用_rand2()函数来决定是选择1~5,还是6~10。想必你应该明白了。

这两个函数都可以通过打表法来生成。

/*生成[1, 2, 3, 4, 5]的方法可以按照打表法来进行
  1次 1 2 3 4 5 1 2    ; = (rand() + 4) % 5 + 1
  2次 3 4 5 1 2 3 4    ; = (rand() + 1) % 5 + 1
  3次 5 1 2 3 4 5 1    ; = (rand() + 3) % 5 + 1
  4次 2 3 4 5 1 2 3    ; = (rand() + 0) % 5 + 1
  5次 4 5 1 2 3 4 5    ; = (rand() + 2) % 5 + 1
  
  以后第6次照第一次来生成

  也可以用如下等价代码来生成。
  用同样的办法可以生成[1, 2]随机数
*/
static int _rand5()
{
	static int i = 0;
	int t = (_rand7() + i) % 5 + 1;
	i = (i + 1) % 5;
	return t;
}

static int _rand2()
{
	static int j = 0;
	int t = (_rand7() + j) % 2 + 1;
	j = !j;
	return t;
}


有了上面两个函数,那么生成[1 10]上的随机函数则比较容易:

首先调用_rand2(),看下是否等于1,如果等于1则直接返回1~5
否则返回6~10
int _rand10()
{
	int v = _rand2();
	if (1 == v)
	{
		return _rand5();
	}
	else return 5 + _rand5();
}


这里再加上测试代码
int main(void)
{
	int rec[11];
	memset(rec, 0, sizeof(rec));
	for (int i = 0; i < 10000000; ++i)
	{
		rec[_rand10()] ++;
	}
	for (int i = 1; i < 11; ++i)
	{
		printf("%.12f\n", (double)(rec[i])/10000000.0);
	}
	return 0;
}



结果输出:
0.100070700000
0.100000000000
0.100049700000
0.099718400000
0.099943200000
0.100126300000
0.099963900000
0.100145500000
0.099947300000
0.100035000000

完整代码给出如下:
#include<stdio.h>  
#include<stdlib.h>
#include<string.h>
static int _rand7()
{
	return rand() % 7 + 1;
}

/*生成[1, 2, 3, 4, 5]的方法可以按照打表法来进行
  1次 1 2 3 4 5 1 2    ; = (rand() + 4) % 5 + 1
  2次 3 4 5 1 2 3 4    ; = (rand() + 1) % 5 + 1
  3次 5 1 2 3 4 5 1    ; = (rand() + 3) % 5 + 1
  4次 2 3 4 5 1 2 3    ; = (rand() + 0) % 5 + 1
  5次 4 5 1 2 3 4 5    ; = (rand() + 2) % 5 + 1
  
  以后第6次照第一次来生成

  也可以用如下等价代码来生成。
  用同样的办法可以生成[1, 2]随机数
*/
static int _rand5()
{
	static int i = 0;
	int t = (_rand7() + i) % 5 + 1;
	i = (i + 1) % 5;
	return t;
}

static int _rand2()
{
	static int j = 0;
	int t = (_rand7() + j) % 2 + 1;
	j = !j;
	return t;
}

int _rand10()
{
	int v = _rand2();
	if (1 == v)
	{
		return _rand5();
	}
	else return 5 + _rand5();
}


int main(void)
{
	int rec[11];
	memset(rec, 0, sizeof(rec));
	for (int i = 0; i < 10000000; ++i)
	{
		rec[_rand10()] ++;
	}
	for (int i = 1; i < 11; ++i)
	{
		printf("%.12f\n", (double)(rec[i])/10000000.0);
	}
	return 0;
}


欢迎大家讨论~~

再给两个参考链接

1 点击打开链接
2点击打开链接


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值