Java抽獎(jiǎng)算法第二例
本文實(shí)例為大家分享了java抽獎(jiǎng)算法,供大家參考,具體內(nèi)容如下
1. 算法分析
根據(jù)概率將獎(jiǎng)品劃分區(qū)間,每個(gè)區(qū)間代表一個(gè)獎(jiǎng)品,然后抽取隨機(jī)數(shù),反查落在那個(gè)區(qū)間上,即為所抽取的獎(jiǎng)品。

2.代碼
核心算法
public class Arithmetic {
// 放大倍數(shù)
private static final int mulriple = 1000000;
public int pay(List<Prize> prizes) {
int lastScope = 0;
// 洗牌,打亂獎(jiǎng)品次序
Collections.shuffle(prizes);
Map<Integer, int[]> prizeScopes = new HashMap<Integer, int[]>();
Map<Integer, Integer> prizeQuantity = new HashMap<Integer, Integer>();
for (Prize prize : prizes) {
int prizeId = prize.getPrizeId();
// 劃分區(qū)間
int currentScope = lastScope + prize.getProbability().multiply(new BigDecimal(mulriple)).intValue();
prizeScopes.put(prizeId, new int[] { lastScope + 1, currentScope });
prizeQuantity.put(prizeId, prize.getQuantity());
lastScope = currentScope;
}
// 獲取1-1000000之間的一個(gè)隨機(jī)數(shù)
int luckyNumber = new Random().nextInt(mulriple);
int luckyPrizeId = 0;
// 查找隨機(jī)數(shù)所在的區(qū)間
if ((null != prizeScopes) && !prizeScopes.isEmpty()) {
Set<Entry<Integer, int[]>> entrySets = prizeScopes.entrySet();
for (Map.Entry<Integer, int[]> m : entrySets) {
int key = m.getKey();
if (luckyNumber >= m.getValue()[0] && luckyNumber <= m.getValue()[1] && prizeQuantity.get(key) > 0) {
luckyPrizeId = key;
break;
}
}
}
if (luckyPrizeId > 0) {
// 獎(jiǎng)品庫(kù)存減一
}
return luckyPrizeId;
}
}
Prize bean
public class Prize {
/**
* 獎(jiǎng)品唯一標(biāo)示
*/
private Integer prizeId;
/**
* 中獎(jiǎng)概率
*/
private BigDecimal probability;
/**
* 獎(jiǎng)品數(shù)量
*/
private Integer quantity;
public Integer getPrizeId() {
return prizeId;
}
public void setPrizeId(Integer prizeId) {
this.prizeId = prizeId;
}
public BigDecimal getProbability() {
return probability;
}
public void setProbability(BigDecimal probability) {
this.probability = probability;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
}
3.測(cè)試
prize1概率: 5%
prize2概率: 10%
prize3概率: 15%
prize4概率: 20%
prize5概率: 50%
public class Test {
public static void main(String[] args) {
List<Prize> prizes = new ArrayList<Prize>();
Prize prize1 = new Prize();
prize1.setPrizeId(1);
prize1.setProbability(new BigDecimal(0.05));
prize1.setQuantity(1);
prizes.add(prize1);
Prize prize2 = new Prize();
prize2.setPrizeId(2);
prize2.setProbability(new BigDecimal(0.10));
prize2.setQuantity(10);
prizes.add(prize2);
Prize prize3 = new Prize();
prize3.setPrizeId(3);
prize3.setProbability(new BigDecimal(0.15));
prize3.setQuantity(20);
prizes.add(prize3);
Prize prize4 = new Prize();
prize4.setPrizeId(4);
prize4.setProbability(new BigDecimal(0.20));
prize4.setQuantity(50);
prizes.add(prize4);
Prize prize5 = new Prize();
prize5.setPrizeId(5);
prize5.setProbability(new BigDecimal(0.50));
prize5.setQuantity(200);
prizes.add(prize5);
int prize1GetTimes = 0;
int prize2GetTimes = 0;
int prize3GetTimes = 0;
int prize4GetTimes = 0;
int prize5GetTimes = 0;
Arithmetic arithmetic = new Arithmetic();
int times = 1000;
for (int i = 0; i < times; i++) {
int prizeId = arithmetic.pay(prizes);
switch (prizeId) {
case 1:
prize1GetTimes++;
break;
case 2:
prize2GetTimes++;
break;
case 3:
prize3GetTimes++;
break;
case 4:
prize4GetTimes++;
break;
case 5:
prize5GetTimes++;
break;
}
}
System.out.println("抽獎(jiǎng)次數(shù)" + times);
System.out.println("prize1中獎(jiǎng)次數(shù)" + prize1GetTimes);
System.out.println("prize2中獎(jiǎng)次數(shù)" + prize2GetTimes);
System.out.println("prize3中獎(jiǎng)次數(shù)" + prize3GetTimes);
System.out.println("prize4中獎(jiǎng)次數(shù)" + prize4GetTimes);
System.out.println("prize5中獎(jiǎng)次數(shù)" + prize5GetTimes);
}
}
結(jié)果:

通過(guò)1000次抽取,我們看出算法精度還是很高的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作
這篇文章主要介紹了springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08
關(guān)于Java中使用jdbc連接數(shù)據(jù)庫(kù)中文出現(xiàn)亂碼的問(wèn)題
這篇文章主要介紹了關(guān)于Java中使用jdbc連接數(shù)據(jù)庫(kù)中文出現(xiàn)亂碼的問(wèn)題,默認(rèn)的編碼和數(shù)據(jù)庫(kù)表中的數(shù)據(jù)使用的編碼是不一致的,如果是中文,那么在數(shù)據(jù)庫(kù)中執(zhí)行時(shí)已經(jīng)是亂碼了,需要的朋友可以參考下2023-04-04
Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫(kù)和表實(shí)現(xiàn)方法
這篇文章主要介紹了Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫(kù)和表,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
如何基于springcloud模擬RPC調(diào)用(Feign)
spring4新特性之web開(kāi)發(fā)增強(qiáng)
springboot配置flyway(入門級(jí)別教程)
SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式

