首页 > 代码库 > 求一组数字序列的分布情况(java)
求一组数字序列的分布情况(java)
最近需要做一个正态分布的函数图像所以要处理一段double序列
写了这个算法
先上效果图:
核心思想:
1先根据步长计算每一个区间
2循环进行判断序列中每个数属于哪个区间
3用一个数组来保存每一个区间中 数的个数
这样就可以得到整个分布函数了 当然效率值得考虑 我的机器1百万以上的数据就会有问题了
这是一个double类型的例子 int型就更容易啦
上代码!
1 package com.huang.distribution; 2 3 import java.math.BigDecimal; 4 import java.util.ArrayList; 5 import java.util.Collections; 6 7 public class DistributeDoubleList { 8 9 /** 10 * @authr huanglizhe 2014-08-09 11 * 对若干个double值进行范围统计 12 */ 13 static int length=100;//随机生成多少个数据 1百万时效率有所下降 14 static int effective_number=3;//决定要保留的小数点后有效位数 15 static BigDecimal temp; 16 static ArrayList<Double> list;//原始数据 17 static double add_data; 18 static double max; 19 static double min; 20 static double range;//等间隔值=(max-min)/space 21 static int space =10;//步长 你要分为几个区间 22 23 public static void main(String[] args) { 24 generatedata(); 25 getrange(); 26 showdata(); 27 distribute(); 28 } 29 30 //生成length个随机double序列 并添加到list中 31 public static void generatedata() 32 { 33 list=new ArrayList<Double>(); 34 for(int i=0;i<length;i++) 35 { 36 temp =new BigDecimal(Math.random()*100);//取0-100随机数 37 //取effective_number=3位有效位 38 add_data=http://www.mamicode.com/temp.setScale(effective_number, BigDecimal.ROUND_HALF_UP).doubleValue(); 39 list.add(add_data); 40 } 41 42 System.out.println("生成数据"); 43 showdata(); 44 } 45 46 //打印已添加好的数据 47 public static void showdata() 48 { 49 System.out.println("list数据---------"); 50 for(int i=0;i<list.size();i++) 51 { 52 System.out.print(" "+list.get(i)); 53 } 54 System.out.println(); 55 System.out.println("list数据---------"); 56 System.out.println(); 57 } 58 59 //得到等间隔的值 60 public static void getrange() 61 { 62 63 Collections.sort(list);//排序 以方便得到最大最小值 64 min=list.get(0); 65 max=list.get(list.size()-1); 66 range=(max-min)/space; 67 temp =new BigDecimal(range); 68 range=temp.setScale(effective_number, BigDecimal.ROUND_HALF_UP).doubleValue(); 69 System.out.println("2:排序并计算min,max,range"); 70 System.out.print("序列min="+min+"\t"); 71 System.out.print("序列max="+max+"\t"); 72 System.out.println("序列range="+range+"\t"); 73 74 75 } 76 77 public static void distribute() 78 { 79 int[] arr=new int[space+1];//用来保存这些值分布个数的数组 80 int k=0; 81 82 //j执行j=add(j,range)的时候会有精度损失所以加到最后个range的时候往往<max 所以要多循环一次 所以会产生多一个k值 83 for(double j=min;j<=add(max,range);j=add(j,range)) 84 { 85 //执行j=add(j,range)后 j就前进了一个范围 86 System.out.print("区间"+k+" ["+j+","+add(j,range)+"] ");//输出范围 87 //循环去除list中的值进行比较 如果j<值<j+range的话则属于这个范围 88 //然后领arr[k]的值+1 89 for(int i=0;i<list.size();i++) 90 { 91 if(list.get(i)>=j&&list.get(i)<add(j,range)) 92 { 93 arr[k]++; 94 } 95 } 96 97 k++;//因为j每次挪动一个范围所以k判断完后也要++ 98 } 99 System.out.println();100 System.out.println("----分布情况arr-------");101 for(int i=0;i<=space;i++)102 {103 104 System.out.print(" "+arr[i]);//最后输出的分布个数105 106 }107 System.out.println();108 109 //简易图像110 for(int i=0;i<=space;i++)111 {112 System.out.print("区间"+i);113 for(int j=0;j<arr[i];j++)114 {115 116 System.out.print("▊");117 }118 119 System.out.println();120 }121 122 123 124 125 }126 127 //处理2个double数相加 避免出现2个相加后等于.013999999999999等情况128 public static double add(double v1, double v2) { 129 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 130 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 131 return b1.add(b2).doubleValue(); 132 } 133 134 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。