给定能随机生成整数 1 到 n 的函数,写出能随机生成整数 1 到 m 的函数(m > n)。
设 n = 5, m = 7
关键是让生成的 1 到 7 的数出现概率相同。调用 n 次给定函数,生成 n 个 1 到 5
之间的随机数,选取最大数所在位置,直到剩下最后一个。如:
初始的 7 个数 [1, 2, 3, 4, 5, 6, 7]。
(1)7 个 1 到 5 的随机数,如 [5, 3, 1, 4, 2, 5, 5];
(2)最大的数(此时为 5)出现的位置为 1,6,7.因此选择[1,6,7](后续步骤是要在这三个
数中选择,直至剩下一个数);
(3)3 个 1 到 5 的随机数,如[2,4,1];
(4)最大的数(此时为 4)出现的位置为 2,因此选择[6]
此时 6 就是产生的 1-7 之间的随机数。
代码如下:
int getRandM(int m)
{
int rands[m + 1], index[m + 1], result[m + 1];
int i, count;
for (i = 1; i <= m; i++)
rands[i] = getRandN();
count = m;
count = indexOfMaxNumber(rands, index, count);
for (i = 1; i <= count; i++)
result[i] = index[i];
do {
for (i = 1; i <= count; i++)
rands[i] = getRandN();
count = indexOfMaxNumber(rands, index, count);
for (i = 1; i <= count; i++)
result[i] = result[index[i]];
} while(count > 1);
return result[1];
}
其中产生1到N的随机函数如下:
int getRandN()
{
// srand((unsigned)time(NULL)); /*随机种子*/
return rand() % N + 1;
}
找出随机数序列中最大数位置的函数如下:
int indexOfMaxNumber(int rands[], int index[], int count)
{
int i, max, countMax;
for (max = rands[1], i = 2; i <= count; i++)
if (rands[i] > max)
max = rands[i];
for (countMax = 0, i = 1; i <= count; i++)
if (max == rands[i])
index[++countMax] = i;
return countMax;
}
测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 5
int getRandN();
int indexOfMaxNumber(int rands[], int index[], int count);
int getRandM(int m);
int main(void)
{
srand((unsigned)time(NULL)); /*随机种子*/
// n = rand() % (Y - X + 1) + X; /*n为X~Y之间的随机数*/
int i;
for (i = 0; i < 10; i++)
printf("%d ", getRandM(7));
printf("\n");
return 0;
}
输出:
下面是Java代码的实现:
import java.util.Random;
public class RandMfromRandN {
private static Random rand = new Random();
private final int n;
public RandMfromRandN(int n) {
this.n = n;
}
public int getRandN() {
return rand.nextInt(n) + 1;
}
public int indexOfMaxNumber(int[] rands, int[] index, int count) {
int max, countMax;
max = rands[1];
for (int i = 2; i <= count; i++)
if (rands[i] > max)
max = rands[i];
countMax = 0;
for (int i = 1; i <= count; i++)
if (rands[i] == max)
index[++countMax] = i;
return countMax;
}
public int getRandM(int m) {
int[] rands = new int[m + 1];
int[] index = new int[m + 1];
int[] result = new int[m + 1];
int count;
for (int i = 1; i <= m; i++)
rands[i] = getRandN();
count = m;
count = indexOfMaxNumber(rands, index, count);
for (int i = 1; i <= count; i++)
result[i] = index[i];
do {
for (int i = 1; i <= count; i++)
rands[i] = getRandN();
count = indexOfMaxNumber(rands, index, count);
for (int i = 1; i <= count; i++)
result[i] = result[index[i]];
} while(count > 1);
return result[1];
}
public static void main(String[] args) {
RandMfromRandN nm = new RandMfromRandN(5);
for (int i = 1; i <= 10; i++)
System.out.print(nm.getRandM(7) + " ");
System.out.println();
}
}
输出: