您的位置:首页 > 编程语言 > Java开发

简单的抽奖系统实现

2017-12-07 14:19 495 查看
需求|原因

朋友突然给我一个抽奖的一个需求,让我帮他他分析下,需求大致是这样的。

1.发起一个抽象活动,选择几种商品作为这个活动的奖品。

2.商品的信息都已经设置好,名称、数量、单个奖品中奖率(存储整数,以万计。比如存的1,中奖率就是万分之一。)

3.实现用户抽奖,并给出是否中奖,如果中奖,什么奖品?

思路分析

例如有3种奖品 iphone(数量:2,中奖率:1),手电(数量:2,中奖率:20),水笔(数量:3,中奖率:20)

注:中奖率是依照万计算的。就是除以10000。

采用随机数的方式来计算,但怎么产生随机数,才能符合这个概率问题呢。

直接看代码吧

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;

class Prize{
String id;
String name;
//奖品个数
int sum;
//中奖率
int probability;
//中奖号码
String winningStr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public int getProbability() {
return probability;
}
public void setProbability(int probability) {
this.probability = probability;
}
public String getWinningStr() {
return winningStr;
}
public void setWinningStr(String winningStr) {
this.winningStr = winningStr;
}

}

/**
* 抽奖号码类,此类只产生中奖号码,
* 思路:在发布一个抽奖活动是,为每个奖品产生中奖号码;
* 当用户来抽奖时,你需要先自己判断奖品数量>0和状态是否存在,如果状态不存在或者数量=0;就直接返回谢谢,未抽中。
* 如果奖品数量>0;就产生一个随机数(main方法里有例子怎么算出随机数的)。然后比较是否中奖了。中奖之后再去查中了什么奖,否则如果不中奖返回谢谢。
*
* @ClassName:  PrizeRandom
* @Description:TODO(这里用一句话描述这个类的作用)
* @author LiYuanyuan
* @date 2017年12月7日 下午1:19:30
*/
public class PrizeRandom {
//默认最大的概率基数
private static final int DEFAULT_MAX_RATE_NUM=10000;

/**
* 获取奖品的对应的中奖号码
* @Title: getWinningCode
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param prizes  奖品对象集合
* @param: @return
* @author LiYuanyuan
* @date 2017年12月7日 上午10:24:06
* @return: Map<String,int[]>
* @throws
*/
public static List<Integer> getAllWinningCode(List<Prize> prizes,int maxRandom,int randomCount){
//保存生成的中奖号码
List<Integer> winningNums = new ArrayList<Integer>();
//产生随机数
for(int i=0;i<randomCount;i++){
winningNums.add(getWinningNum(winningNums,maxRandom));
}
return winningNums;
}

public static Map<String,List<Integer>> getPrizeWinNums(List<Prize> prizes,List<Integer> winningNums, int prizeLSM){
Map<String,List<Integer>> prizesWinNumMap = new HashMap<String,List<Integer>>();
//生成中奖号码的个数
int rateSum = winningNums.size();
//遍历奖品,分配中奖数
int index=0;
for(Prize prize:prizes){
//奖品的中奖号码个数
int probabilitySum = prize.getProbability()*prizeLSM;
//保存奖品分配的中奖数
List<Integer> prizeWinNums = new ArrayList<Integer>();
//从总的中奖号码中随机获取索引下的value
int i=0;
for(;index<rateSum;index++){
//防止在抽取到相同的index,获取相同的数字。所以
prizeWinNums.add(winningNums.get(index));
if(i==probabilitySum-1){
break;
}
i++;
}
index++;
prizesWinNumMap.put(prize.getName(),prizeWinNums);
}
return prizesWinNumMap;
}

/**
* 获取一个奖品的中奖号码
* @param winningNumList  保存中奖号码的List集合
* @param maxRandom  随机数的最大取值范围
* @return 中奖号码
*/
private static int getWinningNum(List<Integer> winningNumList, int maxRandom){
//
int winningNum = getRandom(maxRandom);
if(winningNumList.contains(winningNum)){
winningNum = getWinningNum(winningNumList,maxRandom);
}
return winningNum;
}

/**
* 获取一个小于max的随机数
* @param max 随机数的最大范围 =所有奖品个数的最小公倍数*10000;
* @return  int 随机数
*/
public static int getRandom(int max){
double randomD = Math.random()*max+1;
String randomStr = String.valueOf(randomD);
randomStr = randomStr.substring(0, randomStr.lastIndexOf("."));
return Integer.parseInt(randomStr);
}

/**
* 求最小公倍数
* @Title: getLSM
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param rates   参与活动的所有奖品个数List集合
* @param: @return
* @author LiYuanyuan
* @date 2017年12月7日 上午10:19:38
* @return: int
* @throws
*/
public static int getLSM(List<Integer> rates){
int lsmNum = -1;
int max = getMaxByList(rates);
for(int i=max;;i++){
boolean isExsitLSM = true;
for(int num : rates){
if(i%num!=0){
isExsitLSM = false;
break;
}
}
if(isExsitLSM){
lsmNum = i;
break;
}
}
return lsmNum;
}
/**
* 获取List中的最大值
* @Title: getMaxByList
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param rates
* @param: @return
* @author LiYuanyuan
* @date 2017年12月7日 上午10:19:19
* @return: int
* @throws
*/
private static int getMaxByList(List<Integer> rates){
Arrays.sort(rates.toArray());
return rates.get(rates.size()-1);
}

public static void main(String[] args) {

//初始化一个活动奖品
List<Prize> prizes = new ArrayList<Prize>();
Prize prize = new Prize();
prize.setId("1");
prize.setName("iphoneX");
prize.setSum(1);
prize.setProbability(20);
prizes.add(prize);

prize = new Prize();
prize.setId("2");
prize.setName("手电");
prize.setSum(2);
prize.setProbability(50);
prizes.add(prize);

prize = new Prize();
prize.setId("3");
prize.setName("水笔");
prize.setSum(2);
prize.setProbability(100);
prizes.add(prize);

//定义一个保存所有参与抽奖活动A的所有奖品个数集合
List<Integer> list = new ArrayList<Integer>();
list.add(1);//iphoneX个数
list.add(2);//手电个数
list.add(2);//水笔个数

//求奖品个数的最小公倍数,利用最小公倍数,算出随机数的最大范围。
int prizeMinLSMLSM = getLSM(list);
int maxRandom = prizeMinLSMLSM*DEFAULT_MAX_RATE_NUM;

//求出,每种奖品在最小公倍数作为分母基数时,分子的大小是多少,也就是占用的概率是多少
int rateSum = 0;
for(Prize prizee:prizes){
rateSum+=(prizee.getProbability()*prizeMinLSMLSM);
}

//1.建立一个抽奖活动A时,生成活动奖品号码
//获取所有的中奖号码
List<Integer> allWinningCodes = getAllWinningCode(prizes,maxRandom,rateSum);
//分配中奖号码
Map<String,List<Integer>> prizesWinNumMap = getPrizeWinNums(prizes, allWinningCodes, prizeMinLSMLSM);
System.out.println("本次抽奖活动A的所有奖品幸运号码:");
System.out.println(JSON.toJSON(prizesWinNumMap));

//2.用户抽奖的时候

boolean isLuck = false;//是否中奖
int i = 1;//模仿许多用户抽奖
int luckCount = 0;//中奖次数
while(!isLuck){
//产生一个随机号码
int luckNum = getRandom(maxRandom);
System.out.println("用户 李园园第"+i+"次抽中的号码为:"+luckNum);
//随机号码是否存在于奖品号码里
if(allWinningCodes.contains(luckNum)){
//遍历奖品的中奖号码,查找中奖了那个奖品
for(String key:prizesWinNumMap.keySet()){
if(prizesWinNumMap.get(key).contains(luckNum)){
//遍历奖品
for(Prize prizee:prizes){
if(prizee.getName().equals(key)){
//判断奖品数量
if(prizee.getSum()>0){
prizee.setSum(prizee.getSum()-1);
System.out.println("恭喜中奖了:"+key+ " 剩余奖品数:"+prizee.getSum());
luckCount++;
}else{
System.out.println("---奖品"+key+"派发完了,谢谢惠顾");
isLuck=true;
}
}
}
}
}
}else{
System.out.println("谢谢惠顾");
}
i++;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java