- 背景
有一个抽奖活动,奖品有多种,每种奖品的抽中概率是设定好的,如何写这个抽奖逻辑呢? - 代码案例
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
private Integer id;
private String productName;
private BigDecimal winRate;
}
public static Product draw(List<Product> products) {
BigDecimal decimal = new BigDecimal("10000");
List<Integer> integers = products.stream()
.map(product -> (product.getWinRate().multiply(decimal)).intValue())
.collect(Collectors.toList());
Integer[] arr = new Integer[integers.size()];
arr[0] = integers.get(0);
for (int i = 1, sum = integers.get(0); i < integers.size(); i++) {
arr[i] = sum + integers.get(i);
sum += integers.get(i);
}
int probabilityCount = decimal.intValue();
int randomNum = (int) (Math.random() * probabilityCount);
int index = getIndex(arr, randomNum);
return index == -1 ? null : products.get(index);
}
public static int getIndex(Integer[] arr, int randomNum) {
if (randomNum < arr[0]) {
return 0;
}
for (int i = 1; i < arr.length; i++) {
if (randomNum >= arr[i - 1] && randomNum < arr[i]) {
return i;
}
}
return -1;
}
- 测试
public static void main(String[] args) {
List<Product> products = new ArrayList<>();
products.add(new Product(1, "奖品1", new BigDecimal("0.2")));
products.add(new Product(2, "奖品2", new BigDecimal("0.2")));
products.add(new Product(3, "奖品3", new BigDecimal("0.15")));
products.add(new Product(4, "奖品4", new BigDecimal("0.1")));
products.add(new Product(5, "奖品5", new BigDecimal("0.05")));
products.add(new Product(6, "下次再来", new BigDecimal("0.3")));
double i1 = 0;
double i2 = 0;
double i3 = 0;
double i4 = 0;
double i5 = 0;
double i6 = 0;
int num = 1000000;
for (int i = 0; i < num; i++) {
Product discreteDraw = draw(products);
if (discreteDraw.getId() == 1) {
i1++;
}
if (discreteDraw.getId() == 2) {
i2++;
}
if (discreteDraw.getId() == 3) {
i3++;
}
if (discreteDraw.getId() == 4) {
i4++;
}
if (discreteDraw.getId() == 5) {
i5++;
}
if (discreteDraw.getId() == 6) {
i6++;
}
}
log.info("i1:{},i2:{},i3:{},i4:{},i5:{},i6:{}", i1 / num, i2 / num, i3 / num, i4 / num, i5 / num, i6 / num);
}