import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class AlgorithmUtil {
/**
* 求四分位距
*
* @param param
* @return
*/
public static double fourDivsion(double[] param) {
// 转成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; // 第三四分位
double index = 0; // 记录下标
int indexInt=0;
index = new BigDecimal(len-1).divide(new BigDecimal("4")).doubleValue();
indexInt = new BigDecimal(len-1).divide(new BigDecimal("4")).intValue();
//判断是否可以整除
boolean bQ1 = strivesForTheRemainder(new BigDecimal(index));
//可整除取当前数字
if(bQ1){
q1 = datas[indexInt];
}else{
//不可整除取小数位数字判断与1更靠近的位置
String s = String.valueOf(index);
s = s.substring ( s.indexOf ( "." ) );
s ="0"+s;
double v = Double.parseDouble(s);
String bfb ="";
if(v<0.5){
bfb="0.25";
q1 = datas[indexInt+1].subtract(datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}else if(v>0.5){
bfb="0.75";
q1 = datas[indexInt+1].subtract(datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}else{
bfb="0.5";
q1 = datas[indexInt+1].subtract(datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}
}
index = new BigDecimal(3 * (len - 1)).divide(new BigDecimal("4")).doubleValue();
indexInt = new BigDecimal(3 * (len - 1)).divide(new BigDecimal("4")).intValue();
//判断是否可以整除
boolean bQ3 = strivesForTheRemainder(new BigDecimal(index));
if(bQ3){
q3 = datas[indexInt];
}else{
String s = String.valueOf(index);
s = s.substring ( s.indexOf ( "." ) );
s ="0"+s;
double v = Double.parseDouble(s);
String bfb ="";
if(v<0.5){
bfb="0.25";
q3 = datas[indexInt+1].subtract( datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}else if(v>0.5){
bfb="0.75";
q3 = datas[indexInt+1].subtract( datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}else{
bfb="0.5";
q3 = datas[indexInt+1].subtract( datas[indexInt]).multiply(new BigDecimal(bfb)).add( datas[indexInt]);
}
}
BigDecimal subtract = q3.subtract(q1);
BigDecimal ys =new BigDecimal(0.7413);
BigDecimal multiply = subtract.multiply(ys);
return multiply.doubleValue();
}
/**
* 求一个BigDecimal类型的数字的小数点后面的数,判断该数字能否整除1
* false:有小数,不能整除
* true:没有小数是整数,可以整除
*
* @param bigDecimal
* @return
*/
public static boolean strivesForTheRemainder(BigDecimal bigDecimal) {
String str = bigDecimal.toString();
boolean contains = str.contains(".");
if (contains) {
int index = str.indexOf(".");
String substring = str.substring(index + 1);
int decimals = Integer.parseInt(substring);
if (decimals > 0) {
return false;
}
return true;
}
return true;
}
/**
* 求和
*
* @param arr
* @return
*/
public static double getSum(double[] arr) {
double sum = 0;
for (double num : arr) {
sum += num;
}
return sum;
}
/**
* 求均值
*
* @param arr
* @return
*/
public static double getMean(double[] arr) {
return getSum(arr) / arr.length;
}
/**
* 求均值待带保留位数 (指定值)
*
* @param arr
* @return
*/
public static double getMeanNew(double[] arr,int max) {
double sum = getSum(arr);
BigDecimal sumBig = BigDecimal.valueOf(sum);
BigDecimal leng = BigDecimal.valueOf(arr.length);
//采用四舍六入五成双
BigDecimal divide = sumBig.divide(leng, max, BigDecimal.ROUND_HALF_EVEN);
return divide.doubleValue();
}
/**
* 求标准差
* @param arr
* @return
*/
public static double getStandardDevition(double[] arr) {
double sum = 0;
double mean = getMean(arr);
for (int i = 0; i < arr.length; i++) {
sum += (arr[i] - mean) * (arr[i] - mean);
}
return Math.sqrt((sum / (arr.length - 1)));
}
/**
* 求标准差 用保留位数的指定值做计算
* @param
* @return
*/
public static double getStandardDevition(double[] arr,double median) {
double sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += (arr[i] - median) * (arr[i] - median);
}
return Math.sqrt((sum / (arr.length - 1)));
}
//保留小数一位
public static double formatDouble1(double d) {
// 新方法,如果不需要四舍五入,可以使用RoundingMode.DOWN
BigDecimal bg = new BigDecimal(d).setScale(1, BigDecimal.ROUND_HALF_EVEN);
return bg.doubleValue();
}
//求中位数
public static double median(double[] arr) {
List<Double> total = new ArrayList<Double>();
for (int i = 0; i < arr.length; i++) {
total.add(arr[i]);
}
double j = 0;
//集合排序
Collections.sort(total);
int size = total.size();
if(size % 2 == 1){
j = total.get((size-1)/2);
}else {
//加0.0是为了把int转成double类型,否则除以2会算错
j = (total.get(size/2-1) + total.get(size/2) + 0.0)/2;
}
return j;
}
//求保留指定位数的中位数
public static double median(double[] arr,int max) {
List<Double> total = new ArrayList<Double>();
for (int i = 0; i < arr.length; i++) {
total.add(arr[i]);
}
double j = 0;
//集合排序
Collections.sort(total);
int size = total.size();
if(size % 2 == 1){
j = total.get((size-1)/2);
BigDecimal mData = new BigDecimal(j).setScale(max, BigDecimal.ROUND_HALF_EVEN);
return mData.doubleValue();
}else {
BigDecimal decimal = BigDecimal.valueOf(total.get(size / 2 - 1));
BigDecimal decimal1 = BigDecimal.valueOf(total.get(size / 2));
BigDecimal divide = decimal.add(decimal1).divide(BigDecimal.valueOf(2), max, BigDecimal.ROUND_HALF_EVEN);
return divide.doubleValue();
}
}
public static double ZeroFormat(double num,int n)
{
BigDecimal bigDecimal=new BigDecimal(num);
//DecimalFormat ff = new DecimalFormat("#.0000"); //保留四位小数
//double result = Double.valueOf(ff.format(num));
//return result;
return bigDecimal.setScale(n, BigDecimal.ROUND_HALF_UP).doubleValue();
//setscale(n,BigDecimal.ROUND_HALF_UP).doubleValue;
}
public static void main(String[] args) {
//测试经典统计法,没有问题
/* double[] temp1 = new double[]{14.3,15.4,15,15,15.5,16,16.2,12.5,15.9,13.2,15.5,13.7};
double mean = getMean(temp1);//平均值
double standardDevition = getStandardDevition(temp1);//标准差
for (int i = 0; i <temp1.length ; i++) {
double v = (temp1[i] - mean) / standardDevition;
System.out.println(AlgorithmUtil.formatDouble1(v));
}*/
//四分位距算法,没有问题
// double[] temp1 = new double[]{0.0225, 0.0366, 0.0296, 0.0223, 0.0197, 0.0169,0.0216,0.0198,0.0260,0.0169,0.0216,0.0171,0.0150,0.0300,0.0245,0.0230,0.0184};
// double[] temp1 = new double[]{0.305,0.328,0.360,0.466,0.408,0.655,0.550,0.433,0.466,0.662,0.486,0.544,0.565,0.542,0.692,0.544};
// double[] temp1 = new double[]{22.2,22.5,21.0,22.4,22.0,21.3,22.4,22.3,22.4,20.5,21.3,20.9,22.4,22.2,21.0,22.4,20.6,20.7,20.8,20.9,20.1,20.7,26.3};
// double[] temp1 = new double[]{1,3,4,6,7,9,12,15,16,18,20,25,4,5};
// double[] temp1 = new double[]{2,5,7,9,10,13};
// double v =fourDivsion(temp1);
// boolean b = strivesForTheRemainder(new BigDecimal("40.01"));
// System.out.println(b);
// System.out.println(numberD);
/* double median = median(temp1);
double v = fourDivsion(temp1);
for (int i = 0; i <temp1.length ; i++) {
double c = (temp1[i] - median) / v;
System.out.println(AlgorithmUtil.formatDouble1(c));
}*/
/**
* 均值为 μ标准差σ的正态分布的具体实现
* @param μ double型保留四位小数,表示正态分布均值
* @param σ double型保留四位小数,表示正态分布标准差
* @return S1 double型保留四位小数,表示p(X<x)的正态概率
*/
/* NormalDistribution normalDistributioin = new NormalDistribution(0,1);//新建一个标准正态分布对象
Scanner in=new Scanner(System.in);
do {
System.out.println("请输入ц:");
double ц=in.nextDouble();
//ц=NumberFormat.ZeroFormat(ц);//对所得数据保留4位小数
System.out.println("请输入σ:");
double σ=in.nextDouble();
//σ=NumberFormat.ZeroFormat(σ); //对所得数据保留4位小数
System.out.println("请输入x:");
double x=in.nextDouble();
//x=NumberFormat.ZeroFormat(x);//对所得数据保留4位小数
double z=(x-ц)/σ;
z=ZeroFormat(z,4);//对所得数据保留4位小数
try {
double S1 = normalDistributioin.cumulativeProbability(z);
S1=ZeroFormat(S1,4);//对所得数据保留4位小数
System.out.println("正态分布概率为:");
System.out.println(S1);
System.out.println();
System.out.println("请问您还要继续输入吗?(1/0)");
} catch (Exception e) {
// 这里的异常为所得的结果过小导致异常,直接将结果自动置0
System.out.println("正态分布概率为:");
System.out.println("0");
System.out.println();
System.out.println("请问您还要继续输入吗?(1/0)");
}
} while (in.nextInt()==1);//while循环,当输入的值为1继续,为其他值则终止程序*/
}
}
java 四分位距算法和标准差
于 2022-04-26 10:23:11 首次发布