国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java實現(xiàn)仿微信紅包分配規(guī)則

2019-11-26 14:32:47
字體:
供稿:網(wǎng)友

最近過年發(fā)紅包拜年成為一種新的潮流,作為程序猿對算法的好奇遠(yuǎn)遠(yuǎn)要大于對紅包的好奇,這里介紹一種自己想到的一種隨機(jī)紅包分配策略,還請大家多多指教。

算法介紹

一、紅包金額限制

      對于微信紅包,我們知道沒人隨機(jī)的最小紅包是1分,最大金額是200元,這里我們同樣來設(shè)置紅包的范圍,下面代碼我們統(tǒng)一金錢的單位為分。

//最小紅包額度 private static final int MINMONEY = 1; //最大紅包額度 private static final int MAXMONEY = 200 * 100; 

二、判斷紅包金額是否合法
      注意這一步伴隨著整個算法,我們不僅要在分配紅包之前要判斷金額是否合法,同樣要在每個人暫定隨機(jī)金額后也要判斷剩余的金額是否合法。

private boolean isRight(int money, int count) {  double avg = money / count;  if (avg < MINMONEY) {  return false;  }  if (avg > MAXMONEY) {  return false;  }  return true; } 

三、隨機(jī)產(chǎn)生一個紅包
      這里我們采用隨機(jī)的方式產(chǎn)生一個在MINMONEY和MAXMONEY之間的一個紅包,產(chǎn)生紅包之后,我們需要判斷剩余的錢是否是合法紅包,如果不是合法紅包,我們就重新產(chǎn)生分配方案,在重新產(chǎn)生分配方案的時候,我們需要確定一個事情,是產(chǎn)生的紅包過大還是過小,如果紅包過大,下次就隨機(jī)一個小值到本次紅包金額的一個紅包,如果紅包金額過小,我們就產(chǎn)生一個紅包金額到大值的一個紅包。

private int random(int money, int minS, int maxS, int count) {  //紅包數(shù)量為1,直接返回金額  if (count == 1) {  return money;  }  //如果最大金額和最小金額相等,直接返回金額  if (minS == maxS) {  return minS;  }  int max = maxS > money ? money : maxS;  //隨機(jī)產(chǎn)生一個紅包  int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1;  int money1 = money - one;  //判斷該種分配方案是否正確  if (isRight(money1, count -1)) {  return one;  } else {  double avg = money1 / (count - 1);  if (avg < MINMONEY) {  //遞歸調(diào)用,修改紅包最大金額  return random(money, minS, one, count);  }else if (avg > MAXMONEY) {  //遞歸調(diào)用,修改紅包最小金額  return random(money, one, maxS, count);  }  }  return one; } 

四、實現(xiàn)紅包分配
      這里為了避免某一個紅包占用大量資金,我們需要設(shè)定非最后一個紅包的最大金額,我們把他設(shè)置為紅包金額平均值的N倍;有了一、二、三中的方法,我們就可以來實現(xiàn)紅包的分配了。

//每個紅包最大是平均值的倍數(shù) private static final double TIMES = 2.1;  public List<Integer> splitRedPackets(int money, int count) {  if (!isRight(money, count)) {  return null;  }  List<Integer> list = new ArrayList<Integer>();  //紅包最大金額為平均金額的TIMES倍  int max = (int) (money * TIMES / count);  max = max > MAXMONEY ? MAXMONEY : max;  for (int i = 0; i < count; i++) {  int one = random(money, MINMONEY, max, count - i);  list.add(one);  money -= one;  }  return list; } 

紅包分配方案評估

      上面介紹了紅包的基本算法,下面我們就對算法進(jìn)行一次驗證,假設(shè)有一個200元100份的紅包,我們來看一下最后的分配方案。

完整代碼

 /**  *@Description:  */ package com.lulei.weixin.util;  import java.util.ArrayList; import java.util.List;  import com.lulei.util.JsonUtil;  public class RedPacketUtil {  //最小紅包額度  private static final int MINMONEY = 1;  //最大紅包額度  private static final int MAXMONEY = 200 * 100;  //每個紅包最大是平均值的倍數(shù)  private static final double TIMES = 2.1;   /**  * @param money  * @param count  * @return  * @Author:lulei  * @Description: 拆分紅包  */  public List<Integer> splitRedPackets(int money, int count) {  if (!isRight(money, count)) {  return null;  }  List<Integer> list = new ArrayList<Integer>();  //紅包最大金額為平均金額的TIMES倍  int max = (int) (money * TIMES / count);  max = max > MAXMONEY ? MAXMONEY : max;  for (int i = 0; i < count; i++) {  int one = random(money, MINMONEY, max, count - i);  list.add(one);  money -= one;  }  return list;  }   /**  * @param money  * @param minS  * @param maxS  * @param count  * @return  * @Author:lulei  * @Description: 隨機(jī)紅包額度  */  private int random(int money, int minS, int maxS, int count) {  //紅包數(shù)量為1,直接返回金額  if (count == 1) {  return money;  }  //如果最大金額和最小金額相等,直接返回金額  if (minS == maxS) {  return minS;  }  int max = maxS > money ? money : maxS;  //隨機(jī)產(chǎn)生一個紅包  int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1;  int money1 = money - one;  //判斷該種分配方案是否正確  if (isRight(money1, count -1)) {  return one;  } else {  double avg = money1 / (count - 1);  if (avg < MINMONEY) {  //遞歸調(diào)用,修改紅包最大金額  return random(money, minS, one, count);  }else if (avg > MAXMONEY) {  //遞歸調(diào)用,修改紅包最小金額  return random(money, one, maxS, count);  }  }  return one;  }   /**  * @param money  * @param count  * @return  * @Author:lulei  * @Description: 此種紅包是否合法  */  private boolean isRight(int money, int count) {  double avg = money / count;  if (avg < MINMONEY) {  return false;  }  if (avg > MAXMONEY) {  return false;  }  return true;  }   public static void main(String[] args) {  // TODO Auto-generated method stub  RedPacketUtil util = new RedPacketUtil();  System.out.println(JsonUtil.parseJson(util.splitRedPackets(20000, 100)));  } } 

更多精彩內(nèi)容請點擊《Android微信開發(fā)教程匯總》,《java微信開發(fā)教程匯總》歡迎大家學(xué)習(xí)閱讀。

以上就是本文的全部內(nèi)容,希望對大家學(xué)習(xí)java程序設(shè)計有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 巨鹿县| 铜陵市| 棋牌| 合作市| 黑河市| 左权县| 靖边县| 鱼台县| 旅游| 英吉沙县| 林甸县| 和龙市| 青川县| 武隆县| 奉节县| 丹棱县| 湖口县| 阿拉善右旗| 铜川市| 卢氏县| 云和县| 长阳| 广州市| 邢台县| 宿州市| 乐业县| 航空| 错那县| 乃东县| 邵阳市| 宾川县| 湖北省| 峨眉山市| 日喀则市| 上饶县| 三江| 板桥市| 华安县| 宁陵县| 临颍县| 泰和县|