python随机选择一个幸运观众_从十名观众中随机选取8名幸运观众,不能重复选取同一个观众为幸运观众(CPrimerPlus第十六章第五题)...

本文介绍了CPrimerPlus第十六章第五题的解决方案,即如何从十名观众中随机抽取八名不同的幸运观众。作者首先提出了一种错误的方法,该方法仅保证连续两次抽取的观众不同,但可能多次抽取同一名观众。然后,作者给出了正确的方法,通过在每次抽取后将选中观众从候选名单中移除,确保所有幸运观众不重复。文章附带了两种实现方法的代码示例。
摘要由CSDN通过智能技术生成

其实就是CPrimerPlus第十六章第五题,只不过我把标题写的更生动些啦。

刚开始我理解两次选的人不一样就行了,于是只安排了连续两次选人之间对比,人相同了那么就将第二次选择作废,重来一次,直到选的人不同才采用,这时计数器加1(计数器达到8就停止)。

当然,这种方法是不符合题意的,因为第二次选的幸运观众不会和第一次选的相同,但是第三次可以和第一次相同啊。这样就会有幸运观众多次被选中了。

void RandPrint1(int * p, int size, int num) //p是int数组,可理解为观众的标号(1-10);size表示观众的总数量(10);num表示要抽取的幸运观众的数量(比如是8)。

{int i=0;int PreRand=-1;intRand;

srand((unsigned) time(NULL));//用时间做种,每次产生随机数不一样for(i=0; i

Rand=((int)rand() %size);if(Rand !=PreRand)  //抽取的幸运观众号码与上一个幸运观众号码不同,即两个幸运观众不是同一个人

{

printf("%d", *(p+Rand));

i++;

}

PreRand=Rand;  //这个幸运观众下一轮抽取中就变成了“上一个幸运观众”咯

}

}

第二种方法的话,采用选一个幸运观众,就把他从候选人名单中剔除,免得再选中。而且越选越少,越选越简单明了。就是把存着观众号码的内存不断的移动,覆盖掉已经备选的观众的号码,在剩下的(所有观众数 - 被选观众数)的观众中继续选择幸运观众。

思路可以参见下图:

7141a841634927806037b2334b397ef6.png

void RandPrint2(int * p, int size, intnum)

{intRand;inti;

srand((unsigned) time(NULL));for(i=0; i

{

Rand= (int)rand() %size;

printf("%d", *(p+Rand));

memcpy(p+Rand, p+Rand+1, (size-Rand-1)*sizeof(int)); //内存中一块内容的复制

size--; //选一个就踢出去,从剩下的里面选取幸运观众,这已经被“踢出去”的幸运观众就不会被再次选中了。

}

}

好了,简单的一道题解释了半天,自己也是够啰嗦的了。

一个简单的程序测试这两个函数,如下   (其实这个没什么含义,只是占点篇幅而已,大可不看):

//从一个数组中挑选出指定个数的元素,这些元素是随机选取的,并且不能重复,类似于抽取几名幸运观众

#include #include#include

void RandPrint1(int *, int, int);void RandPrint2(int *, int, int);int main(void)

{int candidates[10] = {1,2,3,4,5,6,7,8,9,10};

RandPrint1(candidates,10,8);

printf("\nRandPrint 1 version is Done!\n");

RandPrint2(candidates,10,8);

printf("\nRandPrint 2 version is Done!\n");return 0;

}void RandPrint1(int * p, int size, int num) //这只能保证不连续抽到相同的幸运观众,不能保证抽到的所有幸运观众都不同。

{int i=0;int PreRand=-1;intRand;

srand((unsigned) time(NULL));//用时间做种,每次产生随机数不一样

if(size

{

printf("numbers is bigger than size, break!\n");

exit(-1);

}for(i=0; i

{

Rand=((int)rand() %size);if(Rand !=PreRand)

{

printf("%d", *(p+Rand));

i++;

}

PreRand=Rand;

}

}void RandPrint2(int * p, int size, intnum)

{intRand;inti;for(i=0; i

{

srand((unsigned) time(NULL));

Rand= (int)rand() %size;

printf("%d", *(p+Rand));

memcpy(p+Rand, p+Rand+1, (size-Rand-1)*sizeof(int)); //内存中一块内容的复制

size--; //选一个就踢出去,从剩下的里面选取幸运观众,这已经被“踢出去”的幸运观众就不会被再次选中了。

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值