最近過年發紅包拜年成為一種新的潮流,作為程序猿對算法的好奇遠遠要大于對紅包的好奇,這里介紹一種自己想到的一種隨機紅包分配策略,還請大家多多指教。
算法介紹
一、紅包金額限制
對于微信紅包,我們知道沒人隨機的最小紅包是1分,最大金額是200元,這里我們同樣來設置紅包的范圍,下面代碼我們統一金錢的單位為分。
1
2
3
4
|
//最小紅包額度 private static final int MINMONEY = 1 ; //最大紅包額度 private static final int MAXMONEY = 200 * 100 ; |
二、判斷紅包金額是否合法
注意這一步伴隨著整個算法,我們不僅要在分配紅包之前要判斷金額是否合法,同樣要在每個人暫定隨機金額后也要判斷剩余的金額是否合法。
1
2
3
4
5
6
7
8
9
10
|
private boolean isRight( int money, int count) { double avg = money / count; if (avg < MINMONEY) { return false ; } if (avg > MAXMONEY) { return false ; } return true ; } |
三、隨機產生一個紅包
這里我們采用隨機的方式產生一個在MINMONEY和MAXMONEY之間的一個紅包,產生紅包之后,我們需要判斷剩余的錢是否是合法紅包,如果不是合法紅包,我們就重新產生分配方案,在重新產生分配方案的時候,我們需要確定一個事情,是產生的紅包過大還是過小,如果紅包過大,下次就隨機一個小值到本次紅包金額的一個紅包,如果紅包金額過小,我們就產生一個紅包金額到大值的一個紅包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
private int random( int money, int minS, int maxS, int count) { //紅包數量為1,直接返回金額 if (count == 1 ) { return money; } //如果最大金額和最小金額相等,直接返回金額 if (minS == maxS) { return minS; } int max = maxS > money ? money : maxS; //隨機產生一個紅包 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) { //遞歸調用,修改紅包最大金額 return random(money, minS, one, count); } else if (avg > MAXMONEY) { //遞歸調用,修改紅包最小金額 return random(money, one, maxS, count); } } return one; } |
四、實現紅包分配
這里為了避免某一個紅包占用大量資金,我們需要設定非最后一個紅包的最大金額,我們把他設置為紅包金額平均值的N倍;有了一、二、三中的方法,我們就可以來實現紅包的分配了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//每個紅包最大是平均值的倍數 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; } |
紅包分配方案評估
上面介紹了紅包的基本算法,下面我們就對算法進行一次驗證,假設有一個200元100份的紅包,我們來看一下最后的分配方案。
完整代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/** *@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 ; //每個紅包最大是平均值的倍數 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: 隨機紅包額度 */ private int random( int money, int minS, int maxS, int count) { //紅包數量為1,直接返回金額 if (count == 1 ) { return money; } //如果最大金額和最小金額相等,直接返回金額 if (minS == maxS) { return minS; } int max = maxS > money ? money : maxS; //隨機產生一個紅包 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) { //遞歸調用,修改紅包最大金額 return random(money, minS, one, count); } else if (avg > MAXMONEY) { //遞歸調用,修改紅包最小金額 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 ))); } } |
更多精彩內容請點擊《Android微信開發教程匯總》,《java微信開發教程匯總》歡迎大家學習閱讀。
以上就是本文的全部內容,希望對大家學習java程序設計有所幫助。