四分位数算法记录(含java代码实现)

计算核验:

1、数列项为奇数时:

3、5、9、11、17、19、35

 

先计算位置,在通过位置计算对应的数值

Q1:(n+1)*0.25=2

Q2:(n+1)*0.5=4

Q3:(n+1)*0.75=6

当下标正好为整数时,对应的数值为Q1=5、Q2=11、Q3=19

 

3、5、9、11、17

Q1:(n+1)*0.25=1.5

Q2:(n+1)*0.5=3

Q3:(n+1)*0.75=4.5

当计算的下标不是整数时,对应的数值为Q1=(3+5)*0.5=4、Q2=9、Q3=(11+17)*0.5=14

 

2. 数列项为偶数时

3、5、9、11、17、19

Q2的值为中间两个数字和除以2

 

Q1位置:(n+1)/ 4 = 1.75

Q3位置:3(n+1)/ 4=5.25

 

对应值得计算为落到位置的区间值,低位+(高位-低位)*小数部分

Q1值:3+(5-3)* 0.75 = 4.5

Q3值:17+(19-17)* 0.25 = 17.5

注意:这里的n为样本数据个数

JAVA代码实现:

public class FourDivsionUtil
{
    private FourDivsionUtil()
    {   
    }

    public static Map<String,BigDecimal> fourDivsion(double[] param)
    {
        if (param == null || param.length < 4) 
        {
            return null;
        }
        // 转成BigDecimal类型,避免失去精度
        BigDecimal[] datas = new BigDecimal[param.length];
        for (int i = 0; i < param.length; i++)
        {
            datas[i] = BigDecimal.valueOf(param[i]);
        }
        int len = datas.length;// 数组长度
        Arrays.sort(datas);    // 数组排序,从小到大
        BigDecimal q1 = null;  // 第一四分位
        BigDecimal q2 = null;  // 第二四分位
        BigDecimal q3 = null;  // 第三四分位
        int index = 0; // 记录下标
        // n代表项数,因为下标是从0开始所以这里理解为:len = n+1
        if (len % 2 == 0)
        { // 偶数
            index = new BigDecimal(len + 1).divide(new BigDecimal("4")).intValue();
            q1 = datas[index - 1].multiply(new BigDecimal("0.25")).add(datas[index].multiply(new BigDecimal("0.75")));
            q2 = datas[len / 2].add(datas[len / 2 - 1]).divide(new BigDecimal("2"));
            index = new BigDecimal(3 * (len + 1)).divide(new BigDecimal("4")).intValue();
            q3 = datas[index - 1].multiply(new BigDecimal("0.75")).add(datas[index].multiply(new BigDecimal("0.25")));
        } else
        { // 奇数
            //不是整数时需要特殊处理
            q1 = dealOddNumber(datas, len, "0.25");
            q2 = dealOddNumber(datas, len, "0.5");
            q3 = dealOddNumber(datas, len, "0.75");
        }
        // 保留两位小数(四舍五入),输出到控制台
        System.out.println(q1 + " " + q2 + " " + q3);
        Map<String,BigDecimal> numParm = new HashMap<String, BigDecimal>();
        numParm.put("q1", q1);
        numParm.put("q2", q2);
        numParm.put("q3", q3);
        return numParm;
    }

    private static BigDecimal dealOddNumber(BigDecimal[] datas, int len, String x)
    {
        BigDecimal q1;
        BigDecimal index = new BigDecimal(len + 1).multiply(new BigDecimal(x));
        if (checkNumberType(index))
        {
            q1 = datas[index.intValue() - 1];
        } else 
        {
            q1 = (datas[index.setScale(0,BigDecimal.ROUND_HALF_UP).intValue() - 1]
                    .add(datas[index.setScale(0,BigDecimal.ROUND_HALF_DOWN).intValue() - 1]))
                    .multiply(Func.parseBigDecimal(0.5));
        }
        return q1;
    }

    private static boolean checkNumberType(BigDecimal number)
    {
        return new BigDecimal(number.intValue()).compareTo(number) == 0;//true 整数 false 小数
    }

    public static void main(String[] args) 
    {
        double[] temp = new double[]{85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 85000, 
                85000.01, 85000.01, 135000.01, 135000.01, 135000.01, 135000.01, 138571.43, 139166.67, 160000, 160000, 160000, 160000};
        double[] temp1 = new double[]{3,5,9,11,17};
        double[] temp2 = new double[]{3,5,9,11,17,19,35};
        double[] temp3 = new double[]{3, 5, 9, 11, 17,19};
        fourDivsion(temp);
        fourDivsion(temp1);
        fourDivsion(temp2);
        fourDivsion(temp3);
    }

}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值