首页 > 代码库 > 求一组数字序列的分布情况(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 }