1. 程式人生 > >java 搶紅包演算法

java 搶紅包演算法

演算法 思路: 
設mm為數額,單位為元
m=mm*100,
m=m-num;
從m範圍內取m1,
m=m-m1+1,
從m範圍內取m2
m=m-m2+1
以此類推....
然後再累加所有切分的數額,與最初的數額比較,
相等則結束,不相等則將差額加入陣列最後一個。
打亂陣列。
/**
     * 遞迴切分紅包
     * @param mm 紅包金額,以分為單位
     * @param number 紅包個數
     * @return
     */
    public List<BigDecimal> cutPack(BigDecimal mm,int number){
        List<BigDecimal> rtnList = new ArrayList<BigDecimal>();
        Random random = new Random();
        int m = mm.intValue()-number;
        if(m<=0){
            for (int i = 0; i < number; i++) {
                rtnList.add(BigDecimal.ONE);
            }
        }else{
            int r = random.nextInt(99) + 1;
            int mn = m*r/100;
            if(mn<1){
                mn = 1;
            }
            rtnList.add(BigDecimal.valueOf(mn));
            m = m-mn+number-1;
            rtnList.addAll(cutPack(BigDecimal.valueOf(m), number - rtnList.size()));
        }

        return rtnList;
    }

    /**
     * 切分所有紅包
     * @param mm 紅包金額,以分為單位
     * @param number 紅包個數
     * @return
     */
    public List<BigDecimal> cutPackAll(BigDecimal mm,int number){
        List<BigDecimal> rtnList = new ArrayList<BigDecimal>();
        List<BigDecimal> moneys = cutPack(mm, number);
        if (moneys != null) {
            BigDecimal b = new BigDecimal(0);
            for (BigDecimal bigDecimal : moneys) {
                b = b.add(bigDecimal);
            }
            //檢查已切分的紅包總額是否=紅包金額,不等於時,剩餘金額直接分配給最後一個
            if(b.intValue()<mm.intValue()){
                BigDecimal last = moneys.remove(moneys.size()-1);
                last=last.add(BigDecimal.valueOf(mm.intValue()-b.intValue()));
                moneys.add(last);
            }

            for(BigDecimal bigDecimal : moneys){
                bigDecimal = bigDecimal.divide(BigDecimal.valueOf(100),2,4);
                rtnList.add(bigDecimal);
            }
            Collections.shuffle(rtnList);
        }

        return rtnList;
    }

測試呼叫:

@Test
    public void test_math(){
        for (int i = 0; i < 5; i++) {
            List<BigDecimal> moneys = cutPackAll(BigDecimal.valueOf(11), 10);
            if (moneys != null) {
                BigDecimal b = new BigDecimal(0);
                for (BigDecimal bigDecimal : moneys) {
                    System.out.print(bigDecimal + "元    ");
                    b = b.add(bigDecimal);
                }
                System.out.print("   總額:" + b+"元 ");
                System.out.println();
            }
        }
    }
測試結果:
0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.02元       總額:0.11元 
0.02元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元       總額:0.11元 
0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.02元    0.01元    0.01元       總額:0.11元 
0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.01元    0.02元    0.01元       總額:0.11元 
0.01元    0.01元    0.01元    0.01元    0.01元    0.02元    0.01元    0.01元    0.01元    0.01元       總額:0.11元