Shell脚本实现不放回抽签(摸球模型)

本文介绍如何使用Shell脚本实现不放回抽签,即模拟摸球模型。博主通过产生随机数并剔除已抽取的数值,确保每次抽取的概率正确。文章详细解释了代码执行过程,特别是`unset`命令的使用,它能清除数组中的某个元素而不影响其他元素的位置。
摘要由CSDN通过智能技术生成

Shell脚本实现不放回抽签

一次偶然的机会,博主进入大乐透投注站,观察到投注机具有随机选号功能,寻思着如果让我用shell实现该功能,应该要怎么写呢。

思路

基本思路就是产生随机数,将随机数与特定的值域联系起来,最后每取出一位数,值域中将该数剔除,保证抽取到值域内剩下的数的概率与实际相同。

代码如下

#!/bin/bash
big_redball_num=5
big_blueball_num=2
big_red_ball=(1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35)
big_blue_ball=(1 2 3 4 5 6 7 8 9 11 12)
double_redball_num=6
double_blueball_num=1
double_red_ball=(1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33)
double_blue_ball=(1 2 3 4 5 6 7 8 9 11 12 13 14 15 16)
function pick_the_ball #$1是抽取的数组,使用该参数必须用""标注  $2是不放回抽取的个数
{
	#将传入的数组用中间数组承接,方便操作
	arr_temp=(${1})
	for((i=0;i<${2};i++))
	do
		num=$[RANDOM%${#arr_temp[@]}]
		arr_last[i]=${arr_temp[${num}]}
		#删除已经抽中的元素,注意:这里的unset让改位置元素变为空,实际还是占有该位置,
		unset arr_temp[${num}]
		#重新构造arr_temp数组(将没有变为空的元素重新组合起来替换掉原来的数组)
		arr_temp=(${arr_temp[@]})
	done
	#冒泡排序
	for((i=0;i<${#arr_last[@]}-1;i++))
	do
		for((j=0;j<${#arr_last[@]}-1-${i};j++))
		do
			if [ ${arr_last[j]} -gt ${arr_last[j+1]} ];then
				x=${arr_last[j]} 
				arr_last[j]=${arr_last[j+1]} 
				arr_last[j+1]=${x}
			fi
		done
	done
	#打印
	for((j=0;j<${2};j++))
	do 
		printf "%02d " ${arr_last[j]}
	done
}
#红
echo -ne "Big   :"
pick_the_ball "${big_red_ball[*]}" "${big_redball_num}"
echo -ne "+ "
#蓝
pick_the_ball "${big_blue_ball[*]}" "${big_blueball_num}"
echo -ne "\n"

#红
echo -ne "Double:"
pick_the_ball "${double_red_ball[*]}" "${double_redball_num}"
echo -ne "+ "
#蓝
pick_the_ball "${double_blue_ball[*]}" "${double_blueball_num}"
echo -ne "\n"

代码执行一次结果:
在这里插入图片描述

代码中unset处详解

比如unset arr_temp[2],将arr_temp[2]的内容变为空,但是arr_temp[3]的值还是在arr_temp[3],并不会移位到arr_temp[2],所以如果下次再抽中arr_temp[2],会打印空。
测试例子

#!/bin/bash 
arr=(1 2 3 4 5 6 7 8 9)

echo ${arr[2]}
unset arr[2]
echo ${arr[@]}
echo ${!arr[@]}

echo ${arr[2]}
unset arr[2]
echo ${arr[@]}
echo ${!arr[@]}

测试结果
在这里插入图片描述
初次写博客,若有不对的地方请大家指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值