SpringBoot實(shí)現(xiàn)抽獎(jiǎng)算法的示例代碼
前言
當(dāng)我們參加各種活動(dòng)和抽獎(jiǎng)時(shí),抽獎(jiǎng)環(huán)節(jié)總是能引起極大興趣和關(guān)注。抽獎(jiǎng)的公正性和隨機(jī)性是保證活動(dòng)公平和成功的重要因素。
本文將介紹抽獎(jiǎng)算法的實(shí)現(xiàn)原理及其在Java編程語言中的應(yīng)用,以幫助讀者了解抽獎(jiǎng)程序的實(shí)現(xiàn)細(xì)節(jié),同時(shí)也為讀者提供一些有用的參考和借鑒。
創(chuàng)建抽獎(jiǎng)表
CREATE TABLE `app_draw_prize` ( `id` bigint NOT NULL, `activity_id` int unsigned DEFAULT NULL COMMENT '活動(dòng)id', `name` varchar(50) DEFAULT NULL COMMENT '獎(jiǎng)品名稱', `url` varchar(200) DEFAULT NULL COMMENT '圖片地址(未使用)', `value` varchar(10) DEFAULT '0' COMMENT '值', `probability` double unsigned DEFAULT '0' COMMENT '概率', `type` tinyint unsigned DEFAULT NULL COMMENT '類型', `status` tinyint unsigned DEFAULT '0' COMMENT '上下架狀態(tài):0下架1上架', `position` tinyint(1) DEFAULT NULL COMMENT '位置', `day_max_times` tinyint unsigned DEFAULT '0' COMMENT '每天最多中獎(jiǎng)次數(shù),大于0時(shí)生效', `month_max_times` tinyint unsigned DEFAULT '0' COMMENT '每月最多中獎(jiǎng)次數(shù),大于0時(shí)生效', `show` tinyint unsigned DEFAULT '0' COMMENT '是否首頁展示中獎(jiǎng)記錄0否1是', `default_prize` tinyint(1) DEFAULT '0' COMMENT '抽獎(jiǎng)上限時(shí)直接返回默認(rèn)獎(jiǎng)品', `ref_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '關(guān)聯(lián)id', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='抽獎(jiǎng)獎(jiǎng)品表';
抽獎(jiǎng)代碼
算法思路
1.將獎(jiǎng)品按集合中順序概率計(jì)算成所占比例區(qū)間,放入比例集合。并產(chǎn)生一個(gè)隨機(jī)數(shù)加入其中,排序。
2.排序后,隨機(jī)數(shù)落在哪個(gè)區(qū)間,就表示那個(gè)區(qū)間的獎(jiǎng)品被抽中。
3.返回的隨機(jī)數(shù)在集合中的索引,該索引就是獎(jiǎng)品集合中的索引。
4.比例區(qū)間的計(jì)算通過概率相加獲得。
private DrawPrize doDrawPrize(Long activityId, Long userId) {
List<DrawPrize> drawPrizes = drawPrizeMapper.selectList(new LambdaQueryWrapper<DrawPrize>()
.eq(DrawPrize::getActivityId, activityId)
.eq(DrawPrize::getStatus, 1)
.orderByDesc(DrawPrize::getProbability));
List<Double> probLists = new ArrayList<>(drawPrizes.size());
Double sumProb = 0D;
for (DrawPrize drawPrize : drawPrizes) {
sumProb += drawPrize.getProbability();
}
if (sumProb <= 0) {
throw new IllegalArgumentException("抽獎(jiǎng)概率設(shè)置錯(cuò)誤");
}
Double rate = 0D;
for (DrawPrize drawPrize : drawPrizes) {
rate += drawPrize.getProbability();
probLists.add(rate / sumProb);
}
double random = Math.random();
probLists.add(random);
Collections.sort(probLists);
DrawPrize drawPrize = drawPrizes.get(probLists.indexOf(random));
if (drawPrize.getDayMaxTimes() > 0) {
//判斷當(dāng)天中獎(jiǎng)次數(shù)
String daily = DateUtil.formatDate(new Date());
Long count = drawRecordMapper.selectCount(new LambdaQueryWrapper<DrawRecord>()
.eq(DrawRecord::getMemberId, userId)
.eq(DrawRecord::getPrizeId, drawPrize.getId())
.eq(DrawRecord::getDaily, daily));
if (count >= drawPrize.getDayMaxTimes()) {
//直接返回謝謝參與
return drawPrizes.stream()
.filter(d -> d.getDefaultPrize() == 1)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("抽獎(jiǎng)錯(cuò)誤"));
}
}
if (drawPrize.getMonthMaxTimes() > 0) {
//判斷當(dāng)月中獎(jiǎng)次數(shù)
Long count = drawRecordMapper.selectCount(new LambdaQueryWrapper<DrawRecord>()
.eq(DrawRecord::getMemberId, userId)
.eq(DrawRecord::getPrizeId, drawPrize.getId())
.eq(DrawRecord::getMonth, DateUtil.month(new Date())));
if (count >= drawPrize.getMonthMaxTimes()) {
//直接返回謝謝參與
return drawPrizes.stream()
.filter(d -> d.getDefaultPrize() == 1)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("抽獎(jiǎng)錯(cuò)誤"));
}
}
return drawPrize;
}到此這篇關(guān)于SpringBoot實(shí)現(xiàn)抽獎(jiǎng)算法的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot抽獎(jiǎng)算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea中項(xiàng)目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決
這篇文章主要介紹了idea中項(xiàng)目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Java位集合之BitMap、BitSet和布隆過濾器示例解析
這篇文章主要介紹了Java中位集合的基本概念、實(shí)現(xiàn)方法以及應(yīng)用場景,包括Bit-Map、BitSet和BloomFilter,Bit-Map通過位操作高效地存儲和查詢元素狀態(tài),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-12-12
SpringBoot項(xiàng)目訪問任意接口出現(xiàn)401錯(cuò)誤的解決方案
今天小編就為大家分享一篇關(guān)于SpringBoot項(xiàng)目訪問任意接口出現(xiàn)401錯(cuò)誤的解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
springboot全局配置文件與多環(huán)境配置的全過程
SpringBoot項(xiàng)目在多環(huán)境配置上表現(xiàn)的非常優(yōu)秀,只需要非常簡單的操作就可以完成配置,下面這篇文章主要給大家介紹了關(guān)于springboot全局配置文件與多環(huán)境配置的相關(guān)資料,需要的朋友可以參考下2021-12-12
SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Java編寫計(jì)算器的常見方法實(shí)例總結(jié)
這篇文章主要介紹了Java編寫計(jì)算器的常見方法,結(jié)合實(shí)例形式總結(jié)分析了Java實(shí)現(xiàn)計(jì)算器功能的常用方法,需要的朋友可以參考下2016-04-04
Java8中Lambda表達(dá)式的理解與應(yīng)用
Java8最值得學(xué)習(xí)的特性就是Lambda表達(dá)式和Stream?API,如果有python或者javascript的語言基礎(chǔ),對理解Lambda表達(dá)式有很大幫助,下面這篇文章主要給大家介紹了關(guān)于Java8中Lambda表達(dá)式的相關(guān)資料,需要的朋友可以參考下2022-02-02
Spring之什么是ObjectFactory?什么是ObjectProvider?
這篇文章主要介紹了Spring之什么是ObjectFactory?什么是ObjectProvider?具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01

