大转盘,抽奖算法,中奖未中奖

思路:将每个都奖品的概率,加入一个数组,然后遍历数组,得到将随机数在的范围的奖品

因为前端值精确到 0.001%,所以存的值是加倍了的100000,换成整数来进行计算

public static final MAX_WINNING_PROBABILITY = 100000;
public static LuckyDrawAwardDoc draw(List<LuckyDrawAwardDoc> awardList){
    int listSize = awardList.size();
    if(awardList == null || listSize <1){      //没有设置奖品
        return null;
    }

    //遍历奖品集合,计算区间最右值,存入int 数组中
    int interval[] = new int[listSize+1];
    for(int i=0;i <= listSize;i++){
        if(i == 0){
            Integer weight = awardList.get(i).getWinningProbability();
            interval[0] = weight;
        }else if(i < listSize){
            Integer weight = awardList.get(i).getWinningProbability();
            Integer lastAwardWeight = interval[i-1];
            //区间最右的数是上一个 区间最右+自己的权重
            interval[i] = weight + lastAwardWeight;
        }else if(i == listSize){   //最后一个未中奖,因为数组下标从0开始
            interval[i] = MAX_WINNING_PROBABILITY;
        }
    }

    //random int 获取随机值
    int maxInterval = interval[listSize-1];
    Random random = new Random();
    int ranVal = random.nextInt(MAX_WINNING_PROBABILITY);
    //遍历int数组,找到随机值是位于哪个区间
    for (int i = 0; i < interval.length; i++) {
        if (i < interval.length-2 && ranVal >= interval[i] && ranVal < interval[i + 1] && ranVal < interval[interval.length-2]){    
            return awardList.get(i + 1);
        }else if (i == 0 && ranVal < interval[0]){
            // 第一个区间之内
            return awardList.get(0);
        }else if(ranVal >= interval[interval.length-2] && ranVal <= MAX_WINNING_PROBABILITY){      //未中奖情况
            return null;
        }
    }
    //抽奖异常
    throw new LuckyDrawException(ErrorCode.DRAW_ERROR) ;
}
发布了30 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_40898368/article/details/96120035