剑城渔翁 2018-08-12 09:49 采纳率: 50%
浏览 2228
已采纳

使用java进行红包分配算法

公司有个红包分发业务模块,需要红包随机生成金额,克提供参数为:
1、红包金额(最小精确到厘:0.001,数据库是用int表示,1元也就是1000厘)
2、红包发放数量
3、红包金额上限
4、红包金额下限
5、金额精度(精度可以理解为随机数能精确到小数哪一位,如范围为:0.01~0.5,如果精确到分的随机数为0.34 or 0.340,如果精确到厘:0.345)

1,2,3,4,5都可以由用户输入或选择,程序可进行判断是否参数不符计算,意思就是:
如果金额为10元,数量为10个,上限就不能大于10-0.001*9=9.991之类的
而且,金额是随用户输入,没有限制10的倍数或者100的倍数,可能会是2546
数量也是由用户输入,也可能为3254等不规则数字
需要程序使用用户金额生成在上限下限范围内随机缺固定的数量的红包个数,我想了好久了
由于数学比较差,而且红包金额可以根据精度调控后面小数位数

  • 写回答

3条回答 默认 最新

  • miaoch 2018-08-15 02:51
    关注

    我写了一个,但是感觉没那么满意

     public class Red {
        private int remain;//金额,单位厘
        private int count;//个数
        private Precision precision;//精度
        private int max;//上限,单位厘 
        private int min;//下限,单位厘
        private int[] redPool;
        private int index;
    
        public static void main(String[] args) {
            int count = 100;
            Red red = Red.newInstance(10 * 1000, count, Precision.FEN, 1 * 1000, 5 * Precision.FEN.getPre());
            int sum = 0;
            for (int i = 0; i < count; i++) {
                int money = red.getRed();
                sum += money;
                System.out.println(money);
            }
            System.out.println("---------------" + sum);
        }
    
        public int getRed() {
            return index < count ? redPool[index++] : 0;
        }
    
        public static Red newInstance(int money, int count, Precision precision, int max, int min) {
            Red red = new Red(money, count, precision, max, min);
            String msg;
            if ("".equals(msg = red.validate())) return red;
            else throw new RuntimeException(msg);
        }
    
        private Red(int money, int count, Precision precision, int max, int min) {
            this.remain = money;
            this.count = count;
            this.precision = precision;
            this.max = max;
            this.min = min;
            init();
        }
    
        private void init() {
            redPool = new int[count];
            int remain_ = remain;
            for (int i = 0; i < count - 1; i++) {
                int max = getRealMax(remain_, count - i);
                int min = getRealMin(remain_, count - i);
                int money = ((int)(Math.random() * (max - min + precision.getPre())) + min) 
                        / precision.getPre() * precision.getPre();//[min, realMax]
                remain_ -= money;
                redPool[i] = money;
            }
            redPool[count - 1] = remain_;
            randomPool();
        }
    
        private void randomPool() {
            for (int i = 0; i < count; i++) {
                int index = (int) (Math.random() * count);
                int temp = redPool[i];
                redPool[i] = redPool[index];
                redPool[index] = temp;
            }
        }
    
        private int getRealMax(int remain, int count) {
            int calMax = remain - ((count - 1) * min);
            return Math.min(calMax, max);
        }
    
        private int getRealMin(int remain, int count) {
            int calMin = remain - ((count - 1) * max);
            return Math.max(calMin, min);
        }
    
        public int getRemain() {
            return remain;
        }
    
        public void setRemain(int remain) {
            this.remain = remain;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public int getMax() {
            return max;
        }
    
        public void setMax(int max) {
            this.max = max;
        }
    
        public int getMin() {
            return min;
        }
    
        public void setMin(int min) {
            this.min = min;
        }
    
        public Precision getPrecision() {
            return precision;
        }
    
        public void setPrecision(Precision precision) {
            this.precision = precision;
        }
    
        private String validate() {
            String msg = "";
            if (remain <= 0) {
                msg = "余额不能为0";
            } else if (remain % precision.getPre() != 0) {
                msg = "余额的精度不对";
            } else if (count <= 0) {
                msg = "红包个数必须为正数";
            } else if (max % precision.getPre() != 0) {
                msg = "上限的精度不对";
            } else if (max <= min) {
                msg = "上限必须大于下限";
            } else if (min % precision.getPre() != 0) {
                msg = "下限的精度不对";
            } else if (min <= 0) {
                msg = "下限必须大于0";
            } else if (getRealMax(remain, count) < getRealMin(remain, count)) {
                msg = "上下限设置错误";
            }
            return msg;
        }
    
    }
    enum Precision {
        LI(1),
        FEN(10),
        JIAO(100),
        YUAN(1000);
    
        private int pre;
        private Precision(int pre) {
            this.pre = pre;
        }
        public int getPre() {
            return pre;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算