微信紅包的隨機算法是怎樣實現的?
作者:佚名
微信紅包的隨機算法是怎樣實現的?本例中我們摒棄“抽取”、“隨機金額”這樣的傳統概念,使錢擁有選擇意識,執行“隨機”行為,自然而然紅包就有了隨機金額的屬性。改變一下思路,別把簡單問題復雜化。
我在知乎上看到這樣一個問題 微信紅包的隨機算法是怎樣實現的?
有人說騰訊大致是這樣實現的:
- public static double getRandomMoney(LeftMoneyPackage _leftMoneyPackage) {
- // remainSize 剩余的紅包數量
- // remainMoney 剩余的錢
- if (_leftMoneyPackage.remainSize == 1) {
- _leftMoneyPackage.remainSize--;
- return (double) Math.round(_leftMoneyPackage.remainMoney * 100) / 100;
- }
- Random r = new Random();
- double min = 0.01; //
- double max = _leftMoneyPackage.remainMoney / _leftMoneyPackage.remainSize * 2;
- double money = r.nextDouble() * max;
- money = money <= min ? 0.01: money;
- money = Math.floor(money * 100) / 100;
- _leftMoneyPackage.remainSize--;
- _leftMoneyPackage.remainMoney -= money;
- return money;
- }
也有人做了正太分布、方差分析、回歸分析、統計模擬等,圖太長我就不貼了。
然而
- 所有答案都是“取時隨機”,即設計“紅包池”的概念,然后在抽取時隨機取數。
- 所有答案都是“錢的隨機”,即隨機金額,然后return。
下面我們換個思路,現在我們把所有的錢換成1分的 硬幣 ,把紅包想象成 罐子 ,然后 撒幣 。
- /**
- * @param count 紅包數
- * @param money 總金額
- * @return
- */
- public static Integer[] ranRedPac(Integer count, Integer money) {
- Integer[] result = new Integer[count];
- for (int i = 1; i <= money; i++) {
- int n = new Random().nextInt(count);
- result[n] = result[n] == null ? 1 : result[n] + 1;
- }
- return result;
- }
- //測試
- public static void main(String[] args) {
- Arrays.asList(ranRedPac(10, 5000000)).forEach(i -> System.out.println(i));
- System.out.println("sum: " + Arrays.asList(ranRedPac(10, 50)).stream().mapToInt(i -> i).sum());
- }
每分錢隨機選擇紅包。
至于什么回歸分析,統計模擬 統統用不上 。
本例中我們摒棄“抽取”、“隨機金額”這樣的傳統概念,使錢擁有選擇意識,執行“隨機”行為,自然而然紅包就有了隨機金額的屬性。
改變一下思路,別把簡單問題復雜化。
我們在編碼設計時,通常會考慮現實生活中的邏輯,并把對象抽象成類,行為抽象成方法。但是,我們偶爾也要考慮思維 反轉 。
當然,我的代碼有一定的弊端。
思維是最重要的。
責任編輯:未麗燕
來源:
SegmentFault