红包计算的方法(通过2倍指数法进行计算,通过线性切割法计算)

Posted gfl-1112

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红包计算的方法(通过2倍指数法进行计算,通过线性切割法计算)相关的知识,希望对你有一定的参考价值。

方法一:

1.方法可灵活对不同数量的人随机产生点开的红包金额

2.采取2倍指数法计算每个人的红包(2倍指数法:根据人数计算平均红包值,将该数放大两倍即随机红包范围,最后一个拿剩下的所有)

3.红包精确到分

4.应确保每个人至少能拿到1分钱的红包

public class RedMoney {
    /**
     * 将金额四舍五入
     * @param cash
     * @return
     */
    public double round(double cash){
        BigDecimal bd=new BigDecimal(cash);
        //CigDecimal是类,不能直接用于计算,所以要获取他的value值
        return bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    /**
     * 获取红包金额的方法
     * @param count
     * @param money
     */
    public void red(int count,double money){
        //目前每个人分到的总金额
        double total=0;
        for(int i=0;i<=count;i++){
            //每个人分到的红包金额
            double cash;
            //要先判断是不是最后一个人,如果是最后一个人则拿到剩下的所以红包
            if(i==count-1){
                cash=round(money);
                System.out.println("最后一个红包金额是:"+cash);
                //计算每个人领的红包总金额
                total+=cash;
                break;
            }
            //利用二倍指数法获取每个人抽取红包金额的随机范围
            //剩余总金额在变,人数也在变
            double avg=round(money/(count-i));
            double range=avg*2;
            cash=round(Math.random()*range);
            //如果这次抽到的小于0.01,则此次不算,跳过重新抽一次
            if(cash<0.01){
                i--;
                continue;
            }
            System.out.println("第"+i+"个人抽到的红包:"+cash);
            //计算剩余总金额
            money-=cash;
            //将剩余总金额保留两位
            money=round(money);
            //目前累计已经抽到的红包总金额
            total+=cash;
        }
        System.out.println("抽取红包的总金额:"+total);
    }

    /**
     * 调用红包生成的方法
     * @param args
     */
    public static void main(String[] args) {
        RedMoney redMoney=new RedMoney();
        redMoney.red(20, 10);
    }
}

方法二:

使用线性分割的方法进行红包计算(在红包总金额的范围内生成红包切割点)

 

public class RedMoney {

    /**
     * 获取红包金额的方法
     * @param count
     * @param money
     */
    public void red(int count,int money){
        double total=0;
        //根据人数创建切割垫
        double[] array=new double[count-1];
        for(int i=0;i<array.length;i++){
            //剩余总金额在变,所以切割点范围在变
            double point=round(Math.random()*money);
            //判断数组中是否已经存在
            if(hasSameElement(array,point)){
                i--;
                continue;
            }
            //判断生成的值是否小于0.01
            if(point<0.01){
                i--;
                continue;
            }
            //将符合条件的切割点添加至切割点数组
            array[i]=point;
        }
        //对红包切割点进行排序
        sort(array);
        //如果是第一个红包
        for(int i=1;i<count;i++){
            double cash;
            if(i==1){
                cash=array[0];
            }
            else if(i==count){
                cash=money-array[array.length-1];
            }
            else{
                cash=array[i-1]-array[i-2];
            }
            cash=round(cash);
            total+=cash;
            System.out.println("第"+i+"个人分到的红包金额是"+cash);
        }
        System.out.println("总金额"+total);
    }


    /**
     * 将金额四舍五入
     * @param cash
     * @return
     */
    public double round(double cash){
        BigDecimal bd=new BigDecimal(cash);
        //CigDecimal是类,不能直接用于计算,所以要获取他的value值
        return bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
    }


    /**
     * 判断数组中是否已经存在该分割点
     * @param array
     * @param value
     * @return
     */
    public boolean hasSameElement(double[] array,double value){
        boolean flag=false;
        //遍历数组
        for(int i=0;i<array.length;i++){
            //判断数组中是否有重复
            if(array[i]==value){
                //如果有则修改标识
                flag=true;
                break;
            }
        }
        return flag;
    }

    /**
     * 冒泡排序法,将红包截点进行排序
     * @param array
     */
    public void sort(double[] array){
        for(int i=1;i<array.length;i++){
            for(int j=0;j<array.length-i;j++){
                if(array[j]>array[j+1]){
                    double temp =array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
        }
    }
    
    /**
     * 调用红包生成的方法
     * @param args
     */
    public static void main(String[] args) {
        RedMoney redMoney=new RedMoney();
        redMoney.red(10,10);
    }
}

 

以上是关于红包计算的方法(通过2倍指数法进行计算,通过线性切割法计算)的主要内容,如果未能解决你的问题,请参考以下文章

切西瓜法实现微信抢红包功能

切西瓜法实现微信抢红包功能

矩阵指数函数与常微分方程组求解

分治策略——斐波那契数列

matlab 小数据法求liyapunov指数

用随机梯度下降法(SGD)做线性拟合