一道笔试题的思考(三)

题目:随机产生5个数,这5个数每个数的范围都在[10,35]之间,5个数的和是定值100,尽量让5个数的概率随机,写出算法??

如,原来a,b,c,d,e都是20,随机后变成a=34b=29c=11d=10e=16,但是他们之和还是100,再次随机后a=11b=21c=13d=28e=27,他们的和还是100。

我的解决思路是,第一个数和第二个数在[10,35]中随机,后面的数随机要满足一定的条件:保证它之后的数随机后能在[10,35]之间,极端不满足的情况是前两个数都随机到35,那么后面的三个数只能都是10了,所以第三个数随机的时候要满足(100-a-b-c)/2>10||(100-a-b-c)/2<35,否则就要重新随机。第四个数跟第三个数的处理方式一样,第五个数是个用100减去前四个数就行。以下是我的实现:

	public static void random(){
		Random r = new Random();
		int b,c,d,e;
		int a = r.nextInt(25)+10;
		b = r.nextInt(25)+10;
		c = r.nextInt(25)+10;
		while((100-a-b-c)/2<10||(100-a-b-c)/2>35){
			c = r.nextInt(25)+10;
		}
		d = r.nextInt(25)+10;
		while((100-a-b-c-d)<10||(100-a-b-c-d)>35){
			d = r.nextInt(25)+10;
		}
		e = 100-a-b-c-d;
		System.out.println("a="+a+"b="+b+"c="+c+"d="+d+"e="+e);
	}
这里又想起一个有关随机的题目:给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数。

要保证rand7的等概率,就不能利用rand5() + rand()%3来实现rand7()函数,可以这样思考,首先构造一个1到n的等概率随机函数randn(),其中n>7,这样在randn函数内1-7之间的数肯定也是等概率的,把大于7的数丢弃就ok了。以下是我的代码:

	//通过rand5随机1-7之间的数
	public static  int rand7(){
		int t = rand5()+(rand5()-1)*5;
		while(t>22){
			t = rand5()+(rand5()-1)*5;
		}
		return t%7+1;//这里把7的整数倍也用求余的方式映射到1-7.
	}
	//随机1-5之间的数
	public static int rand5(){
		Random r = new Random();
		int i = r.nextInt(5)+1;
		return i;
	}
这里又有一个更普遍的题目,通过randn()函数随机randm()函数,randn是等概率随机1-n之间的数,randm是等概率随机1-m之间的数。跟上面的思路一样,很容易写出代码:

//通过randn随机1-m之间的数。
	public static int randm(int n,int m){
		int t = n*n;
		int i=1;
		int max = (t/m)*m; 
		int s = randn(n)+(randn(n)-1)*n;
		while(s>(max+1)){
			s = randn(n)+(randn(n)-1)*n;
		}
		
		return s%m+1;
	}
	//随机1-n之间的数
	public static int randn(int n){
		Random r = new Random();
		int i = r.nextInt(n)+1;
		return i;
	}



©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值