计算核验:
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);
}
}