随机数的两道题

题1:给定N张扑克牌和一个随机函数,设计一个洗牌算法(又称不重复的随机数)

代码:

/*
rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。

srand函数:srand()称为随机数生成器的初始化器。
头文件:<stdlib.h>
定义函数:void srand (unsigned int seed);
函数说明:srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用getpid()来取得目前进程的进程ID或time(0)或time(NULL)的返回值来当做seed。如果每次seed都设相同值(rand()调用时自动设种子为1),rand()所产生的随机数值每次就会一样。

time_t time(time_t *t);
如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。
返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数。
*/


void shuffle(int* cards,int n) {
    if(cards == NULL)
        return ;
	
    srand(time(0));
    for(int i = 0; i < n - 1; ++i){
        //保证每次第i位的值不会涉及到第i位以前
        int index = i + rand() % (n - i);// 产生i到n-1间的随机数 
        int temp = cards[i];//如果此处用swap,记住用异或法swap要先判断两数是否相同
        cards[i] = cards[index];
        cards[index] = temp;
    }
}


题2:等概率无重复的从n个数中选取m个数

问题描述:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内的m个随机整数,要求:每个数选择出现的概率相等,且按序输出。

分析:

依次考虑整数0,1,2,.....,n - 1。通过按序访问整数,我们可以保证输出结果是有序的。 假如我们考虑m = 2,n = 5的情况,那么选择的每一个数字的概率都应该是2/5。在0,1,2,3,4这五个数字中,我们依次对每一个数进行分析:

第一次遇到0时,它的选择概率应该是2/5,如果选中了,我们开始测试第二个数1,这个时候因为0选中了,所以1这个数字的选中概率就变小了,变成1/4了,因为数字1选中的概率 p(1)  =  数字0选中的概率  * (1/4) + 数字0没选中的概率 * (2/4)   = (2/5 * 1/4) + (3/5 * 2/4) = 8/20 = 2/5   


注请意1/4 2/4与2/5的区别!  

即:1.分母一定会减一  2.前一个选中了时,分子减一;前一个没选中,分子不变!   根据这两点即可写出代码!

代码:

void get(int select,int remain)
{
    for(int i = 0; i < n; ++i) {
        if(rand() % remain < select) { //如果选中了,分子就减一。
            printf("%d\n",i);
            select--;
        }
        remain--;
    }
    return;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值