c语言随机抽取函数,Excel随机取值,给你三种解决方案

原标题:Excel随机取值,给你三种解决方案

所谓随机取值,顾名思义,就是从一堆数里,随机抽取几个或几组数;常用于抽奖、抽查、数据随机分组等。

举个栗子,如下图所示,A2:A21是EH培训学院的20名……男女。现在需要从中随机抽取3人,授予38红旗手的称号,并奖励老祝香吻一枚。

232b226e8aee03bfb09b946a8702c2af.png

解法1:辅助列法

使用辅助列,解决此类问题,应是最简单较快捷的一种解法,基本上老少咸宜,稍有函数公式基础就可以掌握了。

首先将C列作为辅助列,C2输入以下公式,并复制填充至C2:C21区域。

=RAND()

RAND函数生成大于等于0、小于1的随机数。

其次,在E2单元格输入以下公式,复制填充至F2:F4区域即可得到抽奖结果了。

=INDEX(A:A,MATCH(LARGE(C:C,ROW(A1)),C:C,))

LARGE(C:C,ROW(A1)),随着公式向下填充,依次从C列里提取第1、2、3最大的数值;再使用INDEX+MATCH的查询套路得出结果。

结果可能如下:

3480f24a3c1f949a966cb8118a45f94b.png

耸肩,摊手:现在问题来了——请问老祝如何亲吻老祝呢?

想想都太有挑战性了。哈哈哈。

解法2:一条公式

好伐,打个响指,那能不能只用一条函数公式得出最终结果?

当然也可以,只是稍显复杂。

选取E2:E4单元格区域,使用数组三键(同时按下Ctrl+Shift+Enter)输入以下公式,即可得出结果。

=INDEX(A:A,RIGHT(SMALL(RANDBETWEEN(1^ROW(2:21),99)/1%+ROW(2:21),ROW(1:3)),2))

RANDBETWEEN(1^ROW(2:21),99),随机取得>=1且<99的20个整数,生成一维纵向内存数组,例如:

{3;17;11;40;64;65;75;83;19;37;88;74;76;17;46;39;43;80;38;92}

之后除以1%,将随机值放大百倍,再加上人名所在行的行号(+ROW(2:21)),使用SMALL函数依次从小到大取值,使用RIGHT函数重新取出行号,最后使用INDEX函数得出抽奖结果。

敲黑板!注意这是一条区域数组公式。

公式的计算原理其实是酱紫;

我们把20位男女所在的行号,看成是座位号。我们对座位号随机加上不同的权重,然后重新进行排队(升序用small,降序用large),得到一个打乱了的座号排列结果,最后依次将人名取出即可。

公式计算结果可能如下:

ee81806187897defb795f3030fef01ad.png

——挑眉!震惊!震惊!!老祝居然如何自恋!自吻3×2次。天啦噜~哈哈哈。

解法3:洗牌吧

VBA的解法也有多种,最不用动脑的是字典法,但效率偏差,此处略过不提。

嗯,分享下最有效率也最有扩展性的洗牌法。

先讲个故事,憋走开……

假设有一名班花,有一天早晨想斗地主,目前的情况很明显是一缺三,于是打算从全班20位同学里随机抽3人。班花把他们喊出教室,排成一字纵队。

第一步,从20人里随机抽取1人。假设抽到的是排在第15位的“随风小妞”。把她揪出来,拖到第1位去,然后把原本排在第1位的某童鞋安排到第15位去。这样,就成功抽取了一名……牌友。现在是2缺2。

第二步,从排在第2位和第20位之间的童鞋里再随机抽取一人——为什么不是从第1位开始抽呢?

“随风小妞”举手回答说她已经被抽过了,不能被抽第二次(意思就是她不欠抽了)。

假设这次抽到了排在第6位的“空空”,把她请出来,送到第2位去,再把原本排在第2位的某同学安排到第6位。现在是3缺1了。

第3步,从第3位到第20位之间的童鞋再随机抽取1人,排到第3位去。这样,队伍里的前3名就是今天的牌友了。恩,加上班花,4人刚好,散队,打牌去。

是的,现在,只要我们把上面的故事翻译成VBA代码,之前的示例问题也就解决了。

代码如下:

Sub ehkjxg()

Dim r, i&, t, x&

Randomize'随机种子初始化

r = [a2:a21]'将学生喊出教室,装入数组r

For i = 1 To 3'抽3个人

x = Int(Rnd() * (UBound(r) - i + 1)) + i

'依次从第1~2……位置起随机抽取学生

t = r(x, 1) '被抽中的学生出列

r(x, 1) = r(i, 1)'前列的学生去被抽中学生的位置

r(i, 1) = t'被抽中的学生站到前排去

Next

[e2].Resize(3, 1) = r’将队伍的前3名学生(抽取结果)放入抽奖区

End Sub

或许有人问,为什么一定要把抽出来的牌友放到队伍前面去?放到队伍后面行不行?另起一队行不行?其实都可以。

这不是问题的关键。问题的关键在于,每抽出一位牌友,他原来的位置务必不能留空,可以由队前或队尾的人补进来。这样,随机取值的范围渐渐收窄,不白抽,亦不抽错。

暂停5秒——写到这儿,天热的我脑袋有点断片,想不起该写或解释什么了。囧。。。

打个哈欠,那就这样吧,再说也都烟消云散了。我是星光,挥手作别,有闲再见吧。

图文作者:看见星光返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值