算法导论的5.1-2题。RANDOM(a,b)将返回一个介于a与b之间的整数,且每个整数出现的机会相等。可调用RANDOM(0,1)。RANDOM(0,1)产生0和1的概率都为0.5。书中没有给RANDOM(0,1)的实现程序,为了便于调程序,我自己写了个random函数来代替RANDOM(0,1),不知道对不对啦。
这道题的实现思路:
这个题目相当于在能随机生成 0, 1 的前提下,要求随机生成 n=b-a+1 个整数。
1、把要生成的数标记为 a, a+1, a+2,..., b-a+1,…,b-1,b
2、取最小的 m,使得 2^m >= n
3、通过随机生成 0,1 的函数生成一个 m 比特整数(随机生成每一位),这样能 随机生成 [0, 2^m) 内的整数。
4、随机生成一个 [0,2^m) 中的整数,如果这个数加a大小在 [a, b] 内,则取这个数为结果。如果这个数加a在 [a, b] 外,则丢弃它,重新生成一个。
程序1
生成10个1到6之间的数字
- #include "iostream.h "
- #include <time.h>
- #include <math.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
- int random() //不知道对不对 等概率产生0和1
- {
- int a;
- a=rand()%2; //rand()%2为随机产生一个0或1,
- return a;
- }
- int FindMinExp(int n) //通过传入random(a, b)中的差值n=b-a+1,取得最小的指数m, 使得 //2^m >= n.
- {
- int m=0; //指数m
- int n1 = n; //差值n
- while(n>=2)
- {
- n /= 2;
- m ++;
- }
- if(pow(2, m)<n1)
- m ++;
- return m; //返回最小的指数m.
- }
- int BinaryToDecimal(char bin[]) //二进制转换为十进制。
- {
- int result = 0;
- char *p = bin;
- while (*p)
- {
- result = (result << 1 ) + (*p - '0');
- p++;
- }
- return (result);
- }
- int Random(int a, int b)//产生a到b之间的随机数 失败则返回-1
- {
- char string[20];
- int i=0, m=0, n = b - a+1;
- m = FindMinExp(n); //取得最小的指数m, 使得 2^m >= n.
- while(m)
- {
- int l=random();
- itoa(l,&string[i++],10);//注意这句很重要 将生成的01数字转换为字符型
- m --;
- }
- int generate_data = BinaryToDecimal (string);//m位比特串对应的整数。
- if(generate_data+a >= a && generate_data +a<=b)//若在[a,b]范围内,则取此数,若不在则丢弃,//重新生成一个。
- return generate_data+a;
- else
- return -1;
- }
- void main()
- {
- srand((unsigned)time(0)); //要把这东西放在这里
- for(int i=0;i<10;)
- {
- int k=Random(1,6);
- if(k!=-1)
- {printf("%d ",k);
- i++;
- }
- }
- }
程序2:
比程序1更简洁,区别在与对于二进制数的处理
- #include "iostream.h "
- #include <time.h>
- #include <math.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
- int random() //不知道对不对 等概率产生0和1
- {
- int a;
- a=rand()%2; //rand()%2为随机产生一个0或1,
- return a;
- }
- int FindMinExp(int n) //通过传入random(a, b)中的差值n=b-a+1,取得最小的指数m, 使得 //2^m >= n.
- {
- int m=0; //指数m
- int n1 = n; //差值n
- while(n>=2)
- {
- n /= 2;
- m ++;
- }
- if(pow(2, m)<n1)
- m ++;
- return m; //返回最小的指数m.
- }
- int Random(int a, int b)
- {
- char string[20];
- int i=0, m=0, n = b - a+1;
- m = FindMinExp(n); //取得最小的指数m, 使得 2^m >= n.
- int generate_data=0;
- while(m)
- {
- generate_data<<=1;
- generate_data=generate_data+ random();
- m --;
- }
- if(generate_data+a >= a && generate_data+a <=b)//若在[a,b]范围内,则取此数,若不在则丢弃,//重新生成一个。
- return generate_data+a;
- else
- return -1;
- }