AA制算法-java

算法源于生活,在生活中我们不缺少发现算法的眼睛,这个问题在北京一起租房的舍友提出的:每个人都有自己的消费,对于一起的在一个月或者是两个。
月内实行AA制。这一个月你出了多少钱,我出了多少钱,然后汇总,最后计算谁补偿给谁,以前都是人手统计,然后计算,效率不高,而且费事,作为一个开发工程师,很有必要将这个问题用算法实现出来,下面就是我写的算法。
/**
* 订单实体:就是消费账单
*/

public class Receipt {
    private int id;
    private long uid;
    private double money;
    private Date inTime;
    private  String reMark;
    private  int state;


    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getInTime() {
        return inTime;
    }

    public void setInTime(Date inTime) {
        this.inTime = inTime;
    }

    public String getReMark() {
        return reMark;
    }

    public void setReMark(String reMark) {
        this.reMark = reMark;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
}

补偿实体

public static class Equzlize {
        private Long equxUid;//谁
        private Long beqUzUid;//给谁
        private Double muchMoney;//给多少

        public Long getEquxUid() {
            return equxUid;
        }

        public void setEquxUid(Long equxUid) {
            this.equxUid = equxUid;
        }

        public Long getBeqUzUid() {
            return beqUzUid;
        }

        public void setBeqUzUid(Long beqUzUid) {
            this.beqUzUid = beqUzUid;
        }

        public Double getMuchMoney() {
            return muchMoney;
        }

        public void setMuchMoney(Double muchMoney) {
            this.muchMoney = muchMoney;
        }
        //第一组训练数据
        //   1      2        3      4         5
        //     3      3        4      2         0
        //               2.4
        //    1     2         3
        //    0.6   0.6      1.6

        //   4          5
        //  -0.4       -2.4
        //第二组训练数据
        //  1     2     3     4      5     6
        //  4     5     6     7      8     9
        //            6.5
        // -2.5 -1.5  -0.5   0.5     1.5  2.5

        /**
         1->give-->4:---->0.5
         1->give-->5:---->1.5
         1->give-->6:---->0.5
         2->give-->6:---->1.5
         3->give-->6:---->0.5
         */
    }

核心算法

 public static List<Equzlize> getEquzlizeList(List<Receipt> reports, List<Long> uIds) {
        List<Equzlize> list = new ArrayList<>();
        float allNum = 0;
        Map<Long, Double> userToAllMoney = new HashMap<>();
        for (Receipt report : reports) {
            allNum = allNum + (float) report.getMoney();
            if (userToAllMoney.containsKey(report.getUid())) {
                userToAllMoney.put(report.getUid(), userToAllMoney.get(report) + report.getMoney());
            } else {
                userToAllMoney.put(report.getUid(), report.getMoney());
            }
        }
        float avg = allNum / uIds.size();
        Map<Long, Double> heightAvgMap = new HashMap<>();//insert
        Map<Long, Double> underAvgMap = new ConcurrentHashMap<>();//out
        for (int i = 0; i < uIds.size(); i++) {
            double d_value = userToAllMoney.get(uIds.get(i)) - avg;
            if (d_value > 0) {
                heightAvgMap.put(uIds.get(i), d_value);
            } else {
                underAvgMap.put(uIds.get(i), d_value);
            }
        }
        for (Map.Entry<Long, Double> entry : heightAvgMap.entrySet()) {
            double heightAvg = entry.getValue();
            double d_money = entry.getValue();
            for (Map.Entry<Long, Double> dentry : underAvgMap.entrySet()) {
                heightAvg = heightAvg - Math.abs(dentry.getValue());
                if (heightAvg < 0) {
                    Equzlize equzlize = new Equzlize();
                    equzlize.setEquxUid(dentry.getKey());
                    equzlize.setBeqUzUid(entry.getKey());
                    //dentry->entry all
                    equzlize.setMuchMoney(Math.abs(d_money));
                    underAvgMap.put(dentry.getKey(), underAvgMap.get(dentry.getKey()) + Math.abs(d_money));
                    list.add(equzlize);
                    break;
                } else {
                    Equzlize equzlize = new Equzlize();
                    equzlize.setEquxUid(dentry.getKey());
                    equzlize.setBeqUzUid(entry.getKey());
                    //dentry->entry little
                    d_money = heightAvg;
                    equzlize.setMuchMoney(Math.abs(dentry.getValue()));
                    list.add(equzlize);
                    underAvgMap.remove(dentry.getKey());
                }
            }
        }
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i).getEquxUid() + "->give-->" + list.get(i).getBeqUzUid() + ":---->" + list.get(i).getMuchMoney());
        }
        return list;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值