Java implements the function of lottery by comparison

The demand is to do the lucky draw function of several small games. There are different lucky draw rules according to different games, and there are many commonalities, which can be summarized as drawing only according to the proportion of prizes, the proportion of prizes and the number of prizes, and segmented drawing. For convenience, these lucky draw rules are uniformly encapsulated in the tool class. The core logic of the lottery is implemented using a discrete algorithm.

I summary

The discrete algorithm is used to segment according to the proportion of prizes, and then generate the interval corresponding to random number matching. First, define the prize entity class, which has the attributes of prizename, prizeweight and prizecount. The following is the core code:

 /**
   * 按比例随机抽取一项
   * @param list 奖品列表
   * @return 类型值
   */
  public static String ratioExtract(List<Prize> list) {
    //非空判断
    if (list==null || list.size()<1) {
      return null;
    }
    //占比之和
    double sum=0.00;
    //分段数组(20,30,60)
    double[] subArray=new double[list.size()+1];
    //将概率分段
    for (int i = 0; i < list.size(); i++) {
      subArray[i]=sum;
      //这里除要考虑奖品所占比重外还要将奖品数量计算分段其中
      sum+=list.get(i).getPrizeWeight()*list.get(i).getPrizeCount();
    }
    //加上取最大的值
    subArray[subArray.length-1]=sum;

    /* 产生随机数 */
    Random random=new Random();
    double rand = random.nextDouble()*sum;

    //返回字符
    String field=null;
    for (int i = 0; i < subArray.length; i++) {
      if (i==subArray.length-1) {
        return field;
      }
      if (rand>=subArray[i] && rand<subArray[i+1]) {
        field=list.get(i).getPrizeName();
        break;
      }
    }
    return field;
  }

2、 Testing

The following is the complete lottery tool class

import lombok.Data;
import org.apache.commons.lang.math.RandomUtils;

import java.util.List;
import java.util.Random;

/**
 * @Description: 抽奖工具类
 * @author: xiake
 * @Date: 2020/1/5 13:23
 * @ModifiedDate:2020/1/5 13:23
 * @Copyright: miaoxaike.com
 */
public class PrizeMathRandom {

  /**
   * 按比例随机抽取一项
   * @param fieldArray 类型值数组
   * @param proportions 与类型值对应 的占比值
   * @return 类型值
   */
  public static String ratioExtract(String[] fieldArray,double[] proportions) {
    //判断两个数组长度是否相等
    if(fieldArray.length!=proportions.length) {
      return "两数组长度不相等,无法执行";
    }

    //占比之和
    double sum=0.00;
    //分段数组(20,60)
    double[] subArray=new double[proportions.length+1];
    //将概率分段
    for (int i = 0; i < proportions.length; i++) {
      subArray[i]=sum;
      sum+=proportions[i];
    }
    //加上取最大的值
    subArray[subArray.length-1]=sum;
    Random random=new Random();
    /* 产生随机数 区间为 (0,sum)*/
    double rand = random.nextDouble()*sum;
    //返回字符
    String field=null;
    for (int i = 0; i < subArray.length; i++) {
      if (rand>=subArray[i] && rand<subArray[i+1]) {
        field=fieldArray[i];
      }
    }
    return field;
  }

  /**
   * 按比例随机抽取一项
   * @param list 奖品列表
   * @return 类型值
   */
  public static String ratioExtract(List<Prize> list) {
    //非空判断
    if (list==null || list.size()<1) {
      return null;
    }
    //占比之和
    double sum=0.00;
    //分段数组(20,60)
    double[] subArray=new double[list.size()+1];
    //将概率分段
    for (int i = 0; i < list.size(); i++) {
      subArray[i]=sum;
      sum+=list.get(i).getPrizeWeight()*list.get(i).getPrizeCount();
    }
    //加上取最大的值
    subArray[subArray.length-1]=sum;

    /* 产生随机数 */
    Random random=new Random();
    double rand = random.nextDouble()*sum;

    //返回字符
    String field=null;
    for (int i = 0; i < subArray.length; i++) {
      if (i==subArray.length-1) {
        return field;
      }
      if (rand>=subArray[i] && rand<subArray[i+1]) {
        field=list.get(i).getPrizeName();
        break;
      }
    }
    return field;
  }

  /**
   * 双重分段抽取,* @param fieldArray 分段数组,参数值用"-"组装(例: {"6-14","14-23","23-32","32-40"})
   * @param proportions 每段出现的概率
   * @return 返回按比例抽取后,分段范围内的随机一个值
   */
  public static Integer ratioExtractDouble(String[] fieldArray,double[] proportions) {
    String string = ratioExtract(fieldArray,proportions);
    String[] split = string.split("-");
    int result = RandomUtils.nextInt(Integer.parseInt(split[1]))+Integer.parseInt(split[0]);
    return result;
  }

  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  class Prize{
    //奖品名称
    private String prizeName;
    //奖品占比
    private double prizeWeight;
    //奖品数量
    private int prizeCount;
  }
}

In addition to the core implementation method, two extended methods are added to meet the rules of the game. Here's a simple test

public static void main(String[] args) {
    //初始化奖品信息
    List<Prize> prizeList=new ArrayList<>();
    prizeList.add(new Prize("一等奖",1,1));
    prizeList.add(new Prize("二等奖",3,4));
    prizeList.add(new Prize("三等奖",6,5));

    for (int i = 0; i < 12; i++) {
      Prize prize = ratioExtract(prizeList);
      if (prize!=null){
        System.out.println("第"+(i+1)+"次,抽中 "+prize.getPrizeName()+" 剩余奖品数量="+prize.getPrizeCount());
      }else {
        System.out.println("第"+(i+1)+"次,奖品已抽完");
      }

    }
  }

The operation effect is as follows

The implementation method is very simple and may be unreasonable, but it is enough to meet the current needs. Basically, the use of arrays and random numbers is not explained in detail. If you have any questions, please leave a message in the comment area!

The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>