C语言示例分析-乒乓球抽取

C语言实现乒乓球随机抽取
本文介绍了如何使用C语言模拟乒乓球抽取过程,从一个包含1到10编号的乒乓球箱中不放回地抽取,直至抽完。文章详细分析了抽取逻辑,并探讨了随机数的获取,包括rand()和srand()函数的使用,提供了两种随机数生成策略的讨论。

C语言示例分析-乒乓球抽取

问题

假定有10个乒乓球,每个乒乓球上写有一个数字,分别为1-10,然后放到一个箱子中,每次往外不放回的抽取一个乒乓球,记录乒乓球上的数字,直到抽完为止,用程序实现该过程。

分析

  • 分析抽取过程,每次抽取一个球,10次即可以抽完。  第1次抽取,从箱子中的10个乒乓球中抽取一个;
  • 第2次抽取,从箱子中的剩下的9个未被抽中的乒乓球中抽取一个;  第3次抽取,从箱子中的剩下的8个未被抽中的乒乓球中抽取一个;
  • 依次论推……

方法转换

在程序设计语言中,单个数据的使用采用变量存储使用,对于相同类型的数据,则采用数组存储使用。上述10个带有数字的乒乓球,亦即有1,2,3,4,5,6,7,8,9,10等10个整数数值参与运算,因此可通过定义一个整型数组用以存储计算,int iVal[10]={1,2,3,4,5,6,7,8,9,10};

通过数组存储运算,数组元素本身为存储单元,在其中存储的数值为我们所需要的数据,数组元素等同于现实中的装乒乓球的箱子,在现实中,我们用一个箱子放10个乒乓球,由于数组iVal有10个元素组成,每个元素中存放一个数值,这等同于我们用10个相同规格的箱子,每个箱子放一个带有数字的乒乓球,这样,我们在现实中从箱子中抽取一个乒乓球,转换为抽乒乓球箱子:

 分析抽取过程,每次抽取一个装乒乓球的箱子,然后查看箱子中球上的数字,10次即可以抽完。

  • 第1次抽取,从10个箱子中抽取一个,查看球对应的值;
  • 第2次抽取,从剩下的9个未被抽中的箱子中抽取一个,查看球对应的值;
  • 第3次抽取,从剩下的8个未被抽中的箱子中抽取一个,查看球对应的值;
  • 依次论推……

由于球的抽取每次是从剩下的球中抽取,在程序中应对应与从剩下的数组箱子中抽取,由于每次抽取都是从剩下的n个中抽取,而对于剩下的箱子(球),其排列顺序都是从1开始,1,2,3,…,n, 亦即每次抽取后剩下的数据需要重新进行排序,而对于数组而言,一旦定义后,其数组是不变的,由于数据的抽取每次都是从1-n,n随着抽取的次数而逐步减小。

对于10个 “数组箱子”而言,从10个随机抽取一个,假定为5号箱子,亦即取到是5个数组元素,下次抽取,需要从1-9号箱子抽取,5号箱子继续使用,10号箱子排除在外,由于我们抽取的是5号箱子,其中的球已经抽出,10号箱子中的球还未抽取,加入我们将5,10箱子中球互换一下,则10号箱子中球为抽取出来的,1-9号箱子中球还未抽取,符合下次抽取规则。依次类推,则运行10次抽取后,满足抽取规则。抽取球的数值为对应数组中数值的倒序输出。

for (int i=n-1;i>=0;i--)
{
  printf(%d”, iVal[i]);
}

随机数获取

随机抽取过程,在软件中是通过随机数实现的。无论何种语言,都应该提供一个随机数函数。
在C语言中取随机数所需要的函数是:

int rand(void);
void srand (unsigned int n);

rand()函数和srand()函数被声明在头文件stdlib.h中,所以要使用这两个函数必须包含该头文件:
#include <stdlib.h>
rand()函数返回0到RAND_MAX之间的伪随机数(pseudorandom)。
RAND_MAX常量被定义在stdlib.h头文件中。其值等于32767,或者更大。

srand()函数使用自变量n作为种子,用来初始化随机数产生器。只要把相同的种子传入srand(),然后调用rand()时,就会产生相同的随机数序列。因此,我们可以把时间作为srand()函数的种子,就可以避免重复的发生。如果,调用rand()之前没有先调用srand(),就和事先调用srand(1)所产生的结果一样。

随机数程序实现

由于随机数的获取,一般情况下,是基于时间生成的,因此需要注意的是,在运行以上代码之前最好设定一下:
srand(time(NULL));//用系统当前时间设置rand()随机序列种子,保证每次运行随机序列不一样。

#include<time.h> 
#include <stdlib.h>

使用方法一:
srand((unsigned int)time(NULL));
for (int i=0;i<10;i++)
{
  printf(%d”,rand());
}

使用方法二:
for (int i=0;i<10;i++)
{
srand((unsigned int)time(NULL));
  printf(%d”,rand());
}

方法一:给出10个不同的随机数,下一次调用,另外10个不同随机数;
方法二:给出10个不同的随机数,下一次调用,同上次调用相同的10个不同随机数;
因此,srand函数的调用,应在rand函数调用以前调用一次即可。

int GetRnd(int n) //获取0-n-1之间随机整数
{
  return rand()%n;
}

代码

#include<time.h> 
#include <stdlib.h>
int GetRnd(int n) //获取0-n-1之间随机整数
{
  return rand()%n;
}


main()
{
srand((unsigned int)time(NULL));
int iVal[10]={1,2,3,4,5,6,7,8,9,10};
int i,k,n=10,tmp;
  for(i=0;i<10;i++)
  {
     k= GetRnd(n);
     printf(%6d”, k);
     /*将k位置的箱子中的球与n位置的箱子中的球进行互换*/
     tmp= iVal[n-1];
     iVal[n-1]= iVal[k];
     iVal[k]= tmp;
     n--; 
   }
  for (int i=10-1;i>=0;i--)
   {
     printf(%d”, iVal[i]);
   }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值