JAVA计算饼图百分比合计不是100的问题处理,最大余额法
背景:
由于各种原因需要后端来计算每个项所占的百分比,但是会发现计算的各项百分比合计不绝对是100,不能简单的对各项使用四舍五入法,舍九法,进一法等。
思路:
使用最大余额法(比例代表制投票制度下,一种议席分配的方法,结尾有描述)
举个具体例子就很好理解:总计29个员工给3个组投票,请计算出各组所占的百分比,精确到整数。
常规计算出百分比如下:
组名 | 票数 | 计算值(%) | 精确到整数 | 小数余额 |
---|---|---|---|---|
A组 | 10 | 34.482..... | 34 | 0.482..... |
B组 | 12 | 41.379..... | 41 | 0.379..... |
C组 | 7 | 24.137..... | 24 | 0.137..... |
但是很明显,计算值存在小数,产品经理要求精确到整数,且最终的百分比合计又需要等于100,还剩下最后一个数分给谁?
按照最大余额法,应该将最后一个数分给小数余额最大的A组(0.482.....)。同理,如果多出两个数,第二多出的数应该分给小数余额第二大的组。
使用java编码实现如下:
为了方便观察,封装了实体类:
@Data
@NoArgsConstructor
public class PercentVo {/*** 数量*/private int number;/*** 百分比*/private int percent;/*** 小数点后的余额,不需要返回给前端*/@JSONField(serialize = false)private Double point;/*** 组名*/private String name;public PercentVo(int number, String name) {this.number = number;this.name = name;}
}
方法及测试类:
public class NumberUtils {/*** 最大余额法,精度为整数** @param list*/public static void calculatePercent(List<PercentVo> list) {//求和:总票数int sum = list.stream().mapToInt(PercentVo::getNumber).sum();for (PercentVo percentVo : list) {double value = percentVo.getNumber() * 100 / (double) sum;int valueInt = (int) value;//设置对应的百分比percentVo.setPercent(valueInt);//获取小数点后的值percentVo.setPoint(value - valueInt);System.out.println("percentVo = " + percentVo);}//求和:当前各项百分比合计。由于我们舍弃了小数位,所以该合计只会小于等于100int curSum = list.stream().mapToInt(PercentVo::getPercent).sum();while (curSum < 100) {//找出小数余额最大的组,对其进行加1PercentVo max = list.stream().max(Comparator.comparingDouble(PercentVo::getPoint)).get();max.setPercent(max.getPercent() + 1);//当前这个数已经加1了,不应该参与下一轮的竞选max.setPoint(0.0);curSum++;}}public static void main(String[] args) {PercentVo v1 = new PercentVo(10, "A组");PercentVo v2 = new PercentVo(12, "B组");PercentVo v3 = new PercentVo(7, "C组");List<PercentVo> list = Arrays.asList(v1, v2, v3);System.out.println("处理前--------------------------");calculatePercent(list);System.out.println("处理后--------------------------");for (PercentVo percentVo : list) {System.out.println(percentVo);}}
}
结果打印如下:
处理前--------------------------
percentVo = PercentVo(number=10, percent=34, point=0.48275862068965836, name=A组)
percentVo = PercentVo(number=12, percent=41, point=0.3793103448275872, name=B组)
percentVo = PercentVo(number=7, percent=24, point=0.137931034482758, name=C组)
处理后--------------------------
PercentVo(number=10, percent=35, point=0.0, name=A组)
PercentVo(number=12, percent=41, point=0.3793103448275872, name=B组)
PercentVo(number=7, percent=24, point=0.137931034482758, name=C组)
扩展:这里为了方便,仅做了精确到整数,还可以扩展为:添加入参2,自定义精度。来提高适用性,思路是一样的。
延申:
最大余额方法(英文:Largest Remainder Method)又称数额制,是比例代表制投票制度下,一种议席分配的方法,相对于最高均数方法。
透过最大余额方法,候选人须以名单参选,每份名单的人数最多可达至相关选区内的议席数目。候选人在名单内按优先次序排列。选民投票给一份名单,而不是个别候选人。投票结束后,把有效选票除以数额。一份名单每取得数额1倍的票数,便能获分配一个议席。每份名单的候选人按原先订立的顺序当选。
如此类推、将议席分配至每份名单的余额,均比数额为低的时候,则从最大余额者顺序分配余下议席;最大余额方法因而得名。
JAVA计算饼图百分比合计不是100的问题处理,最大余额法相关推荐
- [Java]计算从今天算起,100天以后是几月几号,并格式化成xxxx年x月x日的形式打印出来。
Tip: 调用 Calendar 类的 add()方法计算 100 天后的日期 调用 Calendar 的 getTime() 方法返回 Date 类型对象 使用 FULL 格式的 DateForma ...
- JAVA计算斐波那契第100万项的最快算法排名汇总
最近在知乎上看到一个有趣的算法题:斐波那契数列的第一百万项怎么用 C++ 求? 看了几个大神的解答后,注意到很少有用JAVA代码去解决这个问题的,可能一方面java对这种超大数高精度的运算本身就不是特 ...
- Echarts饼图百分比算法利用Java实现
问题:在开发中有这样的问题,就是需要在其他地方展示百分比,但是自己计算的百分比通过四舍五入后,与饼图里面的百分比不一致的问题,要想解决这个问题,那么必须要使用echarts源码中的计算方式.当存在四舍 ...
- echarts饼图百分比不为100%
一.问题 由于需要兼容低版本ie,使用的echarts版本较低,为2.2.x.当前版本有饼图百分比不为100%的问题,如数据为如下: [ { name: '测试1', value: 1 }, { na ...
- JAVA计算:用 100 元钱买 100 支笔,其中钢笔 3 元 / 支,圆珠笔 2 元 / 支,铅笔 0.5 元 / 支,问钢笔、圆珠笔和铅笔可以各买多少支 ?
Java 计算 用 100 元钱买 100 支笔,其中钢笔 3 元 / 支,圆珠笔 2 元 / 支,铅笔 0.5 元 / 支,问钢笔.圆珠笔和铅笔可以各买多少支 ? 穷举法,用JAVA写了一下,代码很 ...
- Java计算1到100阶乘和
Java计算1到100阶乘和 1.定义一个 factorial类 2.定义一个测试类Cs2 1.定义一个 factorial类 import java.math.BigDecimal; public ...
- java 画饼图和图案
一. 饼图 import java.awt.*;import javax.swing.*;import java.awt.event.*;import java.math.*;import java. ...
- java如何计算时间天数差,java计算两个时间相差天数的方法汇总
问题描述: 输入:两个日期 输出:两个日期相差的天数 具体代码实现 方法1: 通过calendar类的日期比较.注意:这里需要考虑一下: 日期是跨年份的,如一个是2012年,一个是2015年的 年份是 ...
- Cognos 10.1 饼图百分比小数点显示的问题
早上用Cognos 10.1 做了一张销售百分比的饼图,发现有一个区域的销售显示0%.之后在数据中添加了计算项百分比,保留两位小数.在饼图显示值中直接使用计算的百分比,保留两位小数位,结果值竟然直接不 ...
最新文章
- 智源论坛(第5期)活动报名 | 机器学习系列报告会(7月4日、10日)
- (转载)MyEclipse github
- linux命令tcpdump
- POJ 2492 A Bug's Life 带权并查集
- ubuntu安装远程桌面连接工具
- 【漫画】最近,老王又双叒get了CDN的新技能—可编程化敏捷开发
- Tensorflow 学习二 tf.Session().run
- 哈尔滨现大雾天气 高速封闭航班推迟起飞
- jsp 基本语法学习笔记
- 选offer的5个维度
- 又一款性能调优神器,真香!
- Mybatis Sql 大于号小于号不兼容
- uniapp 小程序生成二维码 (兼容H5、微信小程序)
- Unity 5.x游戏开发指南笔记(一)
- Egret + P2物理引擎入门教程
- 页面置换算法(FIFOLRU)
- 《翻译与本地化CAT软件实用教程》目录
- ipadpro编写java代码_iPad Pro变生产力工具,你还缺个轻量级浏览器端代码编辑器...
- VS2005中使用Qt4.8.5遇到的问题
- can总线隔离中继器、canbridge-100、CanRepeater的can波特率和滤波设置