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

使用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 有没有整苹果智能分拣线上图像数据
  • ¥20 有没有人会这个东西的
  • ¥15 cfx考虑调整“enforce system memory limit”参数的设置
  • ¥30 航迹分离,航迹增强,误差分析
  • ¥15 Chrome Manifest扩展引用Ajax-hook库拦截请求失败
  • ¥15 用Ros中的Topic通讯方式控制小乌龟的速度,走矩形;编写订阅器代码
  • ¥15 LLM accuracy检测
  • ¥15 pycharm添加远程解释器报错
  • ¥15 如何让子窗口鼠标滚动独立,不要传递消息给主窗口
  • ¥15 如何能达到用ping0.cc检测成这样?如图