给定1到N的随机数函数,产生1到M的随机数


给定能随机生成整数 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();
    }
} 

输出:




评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值