随机数生成

随机数生成

今天课上学习了猜数字游戏的实现,用到随机数,但只是生成1~100之间的随机数,感觉比较简单。课后想到,如果想生成更大范围的随机数,应该怎么做呢?例如生成介于min 和 max之间的随机数,应该怎么实现?下来仔细思考了一下,发现还是有点意思的。现在将思路记录下来。

思路

首先考虑min 和 max的范围,这个完全可以转换成min + (0,max-min)这个即可。所以我们至需要考虑0~(max-min)之间即可。C语言中,rand函数只能生成最大值为32767的随机数,超过这个范围可能需要一些运算才能实现。
我们先观察一个比较大的数字,例如654321。这个数字可以写成65X100001 + 4321X100000 。那么我们可以生成0至4321之间的随机数sum0,然后再生成0至65之间的随机数sum1,然后按照ret = sum1X100001 +sum2X100000 将这两个值加起来就可以得到最后想要的数字了。有了这个思路,尝试写一下代码。

计算指数

根据上面的思路,先计算指数。指数这里比较简单,数字的位数如果<=4,指数为0,否则的话指数为位数/4。那么就可以写代码了:

while (max)
{
	max /= 10;
	digits++;//计算位数
}
int divi = 0;//计算指数
if (digits <= 4)
{
	divi = 0;
}
else
	divi = digits / 4;

随机数计算

对于任意的数字,我们首先利用%取后4位,然后使用rand()函数就可以得到0后4位的随机数。然后将这个值/10000,再用%取出后4位,再次利用`rand()`得到0新后4位的随机数,这个数字再*10000,加到之前的数字上。之后就一直重复这个过程,直到最初的数字为0。看一下代码:

while (Max_Init)
{
	sum = 0;
	for (int i = 0; i <= divi; i++)
	{
		int sum0 = Max_Init % 10000;//处理整万情况
		if (0 == sum0)
		{
			sum0 = 9999;
		}
		int sum1 = rand() % sum0;
		sum += sum1 * pow(10000, i);
		Max_Init /= 10000;
	}
}

写代码的时候碰到的坑

  1. 首先就是碰到类似50000这种情况。由于50000%10000 = 0,那么在计算上述代码中的sum1时,会报错,因此做了判断。如果0==sum0,说明是整万,那么直接给sum0赋值9999就可以了;
  2. 计算指数的时候,位数和指数直接不是 指数 = 位数/4,这个公式仅在位数>4的时候成立,因为如果位数是4,位数/4 = 1,但这里指数是需要为0的(只有4位数)。

看一下完整的代码(方便测试写成多组输入了):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main()
{
	srand((unsigned int)time(NULL));
	long long min = 0;
	long long max = 0;
	long long sum = 0;
	while (scanf("%lld %lld", &min, &max) != EOF)
	{
		max = max - min;
		long long Max_Init = max;
		int digits = 0;
		//数位数
		while (max)
		{
			max /= 10;
			digits++;//计算位数
		}
		int divi = 0;
		if (digits <= 4)
		{
			divi = 0;
		}
		else
			divi = digits / 4;

		while (Max_Init)
		{
			sum = 0;
			for (int i = 0; i <= divi; i++)
			{
				int sum0 = Max_Init % 10000;
				if (0 == sum0)
				{
					sum0 = 9999;
				}
				int sum1 = rand() % sum0;
				sum += sum1 * pow(10000, i);
				Max_Init /= 10000;
			}
		}
		sum += min;

		printf("%lld\n", sum);
	}
	return 0;
}

运行结果:

在这里插入图片描述

一些说明

没有参考任何资料,也没有去看别人的代码。我相信一定有比我这种方法更加优秀的方法,这里只是作为一个小小的扩展练习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值