Java抽獎(jiǎng)?chuàng)屬?gòu)算法
本文示例為大家分享了Java抽獎(jiǎng)?chuàng)屬?gòu)算法,供大家參考,具體內(nèi)容如下
應(yīng)用場(chǎng)景
單件獎(jiǎng)品搶購(gòu)(可限時(shí))
多件獎(jiǎng)品按概率中獎(jiǎng)(可限時(shí)、可不限量)
代碼實(shí)現(xiàn)
表結(jié)構(gòu):
--抽獎(jiǎng)設(shè)置 create table AWARD_INFO ( ID NUMBER(11) not null, ACT_ID NUMBER(11), --活動(dòng)ID NUM NUMBER(11), --獎(jiǎng)品總量(0為不限量) REST NUMBER(11), --獎(jiǎng)品余量 ODDS NUMBER(11) default 0, --中獎(jiǎng)概率 START_DATE DATE, --開始日期(可為空) END_DATE DATE, --結(jié)束日期(可為空) PRODUCT_ID NUMBER(11), --獎(jiǎng)品ID STATE NUMBER(5) default 0, --狀態(tài) 0-有效 1-失效 INFO_TYPE NUMBER(5) default 0 --0-正常 ); alter table AWARD_INFO add constraint PK_AWARD_INFO primary key (ID); --中獎(jiǎng)紀(jì)錄 create table AWARD_LOG ( id number(11), act_id number(11), --活動(dòng)ID get_time date, --中獎(jiǎng)時(shí)間 product_id number(11), --獎(jiǎng)品ID num number(11) default 1, --中獎(jiǎng)數(shù)量 person varchar2(50), --中獎(jiǎng)人 info_id number(11), --抽獎(jiǎng)設(shè)置ID state number(5) --狀態(tài) 0-有效 1-失效 ); alter table AWARD_LOG add constraint PK_AWARD_LOG primary key (ID);
代碼:
public static class AwardResult{ public int ret; //返回結(jié)果 public int logId; //AWARD_LOG id } /** * 抽獎(jiǎng)算法 * @param actId 抽獎(jiǎng)活動(dòng)ID * @param person 抽獎(jiǎng)人 * @param productId 獎(jiǎng)品ID -1則為該活動(dòng)ID下所有獎(jiǎng)品 * @param excludeId 排除獎(jiǎng)品ID -1 則不排除,與productId不能同時(shí)>0 * @param checkDate 是否檢查時(shí)間 * @return -1 沒有抽獎(jiǎng)數(shù)據(jù);-2 獎(jiǎng)品已抽完; -3 其他錯(cuò)誤;>=0 中獎(jiǎng)productId; -4 排除id * @throws Exception */ public static AwardResult getAwardFull(int actId, String person, int productId, int[] excludeIds, boolean checkDate) throws SQLException{ AwardResult result = new AwardResult(); Connection conn = JDBC.getConnection(); conn.setAutoCommit(false); try{ List<Map<String,Object>> rows; String sql; String checkDateStr = ""; String baseSql = "select t.id, t.product_id, t.num, t.rest, t.odds, t.info_type from award_info t where t.act_id=? and t.state=0 "; if(checkDate){ checkDateStr = " and t.start_Date <= sysdate and t.end_Date >= sysdate "; } if(productId > 0){//搶購(gòu) sql = baseSql + " and t.product_id=? " + checkDateStr + " for update"; rows = JDBC.getRows(sql, new Object[]{actId, productId}, conn); }else{//活動(dòng)所有物品抽獎(jiǎng) sql = baseSql + checkDateStr + " for update"; rows = JDBC.getRows(sql, new Object[]{actId}, conn); } if(rows.isEmpty()){//沒有抽獎(jiǎng)數(shù)據(jù) log.info("沒有抽獎(jiǎng)數(shù)據(jù) actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); conn.commit(); result.ret = -1; return result; } int infoId = -1; int getProductId = -1; int num = -1; int rest = -1; if(rows.size() == 1){//搶購(gòu) num = ((Number)rows.get(0).get("NUM")).intValue(); rest = ((Number)rows.get(0).get("REST")).intValue(); infoId = ((Number)rows.get(0).get("ID")).intValue(); getProductId = ((Number)rows.get(0).get("PRODUCT_ID")).intValue(); }else{//抽獎(jiǎng) int[][] temp = new int[rows.size()][3]; int sum = -1; int i = 0; for(int k = 0; k < rows.size(); k++){//設(shè)置獎(jiǎng)品池 int odds = ((BigDecimal)rows.get(k).get("ODDS")).intValue(); sum++; temp[i][0] = sum; //起始值 sum = sum + odds; temp[i][1] = sum; //結(jié)束值 temp[i][2] = k; //rows index i++; } //抽獎(jiǎng) Random random = new Random(); int r = random.nextInt(sum + 1); int j = 0; for(int k = 0; k < i; k++){ if(r >= temp[k][0] && r <= temp[k][1]){ j = k; break; } } infoId = ((BigDecimal)rows.get(temp[j][2]).get("ID")).intValue(); getProductId = ((BigDecimal)rows.get(temp[j][2]).get("PRODUCT_ID")).intValue(); num = ((Number)rows.get(temp[j][2]).get("NUM")).intValue(); rest = ((Number)rows.get(temp[j][2]).get("REST")).intValue(); } //判斷是否排除id if(ArrayUtils.contains(excludeIds, getProductId)){ log.info("是排除ID actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); conn.commit(); result.ret = -4; return result; } //存量不足 if(num > 0 && rest <= 0){ log.info("獎(jiǎng)品已清空 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); JDBC.commit(conn); result.ret = -2; return result; } //更新獎(jiǎng)品記錄 if(num > 0){//非不限量 sql = "update award_info set rest = rest - 1 where id = ?"; JDBC.update(sql, new Object[]{infoId}, conn); } //記錄獲獎(jiǎng)名單 AwardLog log = new AwardLog(); log.setActId(actId); log.setNum(1); log.setPerson(person); log.setProductId(getProductId); log.setInfoId(infoId); Number logId = log.save(conn); if(logId == null){ throw new SQLException("save award_log error"); } result.logId = logId.intValue(); conn.commit(); result.ret = getProductId; return result; }catch(SQLException e){ log.error("getAward error", e); conn.rollback(); }finally{ JDBC.close(conn); } result.ret = -3; return result; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于Java實(shí)現(xiàn)抽獎(jiǎng)系統(tǒng)
- 簡(jiǎn)單實(shí)現(xiàn)java抽獎(jiǎng)系統(tǒng)
- 純java代碼實(shí)現(xiàn)抽獎(jiǎng)系統(tǒng)
- Java抽獎(jiǎng)算法第二例
- Java實(shí)現(xiàn)雙色球抽獎(jiǎng)隨機(jī)算法示例
- Java簡(jiǎn)易抽獎(jiǎng)系統(tǒng)小項(xiàng)目
- JAVA實(shí)現(xiàn)用戶抽獎(jiǎng)功能(附完整代碼)
- java實(shí)現(xiàn)幸運(yùn)抽獎(jiǎng)系統(tǒng)
- JAVA使用隨機(jī)數(shù)實(shí)現(xiàn)概率抽獎(jiǎng)
- Java使用HashMap映射實(shí)現(xiàn)消費(fèi)抽獎(jiǎng)功能
相關(guān)文章
解決mybatis中resultType取出數(shù)據(jù)順序不一致的問題
這篇文章主要介紹了解決mybatis中resultType取出數(shù)據(jù)順序不一致的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單
這篇文章主要為大家詳細(xì)介紹了SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08javascript與jsp發(fā)送請(qǐng)求到servlet的幾種方式實(shí)例
本文分別給出了javascript發(fā)送請(qǐng)求到servlet的5種方式實(shí)例與 jsp發(fā)送請(qǐng)求到servlet的6種方式實(shí)例2018-03-03詳解使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像
本篇文章主要介紹了使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像,實(shí)例分析了使用JavaCV/OpenCV抓取并存儲(chǔ)攝像頭圖像的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼
這篇文章主要介紹了Java中List、Set、Map的區(qū)別和實(shí)現(xiàn)方式示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06