近期碰到的一個需求,實現一個相似大轉盤抽獎的功能,需自定義獎項,各獎項中獎機率,當日抽獎最大次數,抽獎成本等。分享一個簡單的java代碼的實現的思路,有不足之處感謝各位指正。
java
首先要定義幾個獎品,例如:算法
總的中獎機率是 10%+30%+50%=90%數組
剩餘10%是謝謝惠顧,不中獎的dom
這個是把全部商品按照機率分配到數組裏面iphone
A[10] = iphone優化
...設計
而後隨機一個0到99的數字,例如如今隨機的數字是2code
那麼A[2]就是中獎的商品A[2] = iphoneip
//定義中獎率分母 百分之 int probabilityCount = 100; String[] prizesId = new String[probabilityCount]; //獲取商品列表 List<AdPrizeInfo> prizeInfoList = prizeInfoService.getPrizeInfo(); int num = 0; //循環全部商品 for (AdPrizeInfo prize : prizeInfoList) { Integer probability = prize.getOdds(); //循環商品機率 for (int i = 0; i < probability; i++) { prizesId[num] = prize.getId(); num ++; } } //隨機一個數字 int index = (int) (Math.random() * probabilityCount); //獲取到隨機商品ID String prizeId = prizesId[index];
以上方法若是大機率的話,是很吃內存的,整理優化爲一下方法:內存
使用範圍算法
//定義中獎率分母 百分之 int probabilityCount = 100; //最小几率值 String min = "min"; //最大機率值 String max = "max"; Integer tempInt = 0; //待中獎商品數組 Map<String,Map<String,Integer>> prizesMap = new HashMap<>(); //獲取商品列表 List<AdPrizeInfo> prizeInfoList = prizeInfoService.getPrizeInfo(); for (AdPrizeInfo prize : prizeInfoList) { Map<String,Integer> oddsMap = new HashMap<>(); //最小几率值 oddsMap.put(min,tempInt); tempInt = tempInt + prize.getOdds(); //最大機率值 oddsMap.put(max,tempInt); prizesMap.put(prize.getId(),oddsMap); } //隨機一個數字 int index = (int) (Math.random() * probabilityCount); AdPrizeInfo prizeInfo = null; Set<String> prizesIds = prizesMap.keySet(); for(String prizesId : prizesIds){ Map<String,Integer> oddsMap = prizesMap.get(prizesId); Integer minNum = oddsMap.get(min); Integer maxNum = oddsMap.get(max); //校驗index 再哪一個商品機率中間 if(minNum <= index && maxNum > index){ prizeInfo = prizeInfoService.selectByPrimaryKey(prizesId); break; } } //若是爲空,則沒中獎 if(prizeInfo == null){ prizeInfo = null; }