1.1.32 Histogram 直方图

    该题目来源于Robert Sedgewick 的《算法》。

1.1.32 Histogram. Suppose that the standard input stream is a sequence of double values. Write a program that takes an integer N and two double values l and r from the command line and uses StdDraw to plot a histogram of the count of numbers in the standard input stream that fall in each of the N intervals defined by dividing (l, r) into N equal-sized intervals.

     1.1.32 直方图。 假设标准输入流中是一系列double值。写一个程序从命令行接受一个整数 N 和两个double值 l 和 r ,将(l,r) 分成N段,并使用StdDraw画出输入流的值落入每段的数量的直方图。

在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量。 直方图是品质管理七大工具之一。【来源于维基百科】

首先做一个柱状图,了解一下 StdDraw类中filledRectangle的方法:

    /**
     * bar chart example
     */
    public static void barChart(){
        int N = 5;
        double[] a = new double[N];
        for (int i = 0; i < N; i++) {
            a[i] = StdRandom.random();
        }

        for (int i = 0; i < N; i++) {
            //矩形一半的宽
            double rw = 0.5 / N;
            // 矩形一半的高
            double rh = a[i] /2.0;
            //矩形中心点x轴的坐标
            double x = 1.0 * i / N + 1.0 / N / 2;
            // 矩形中心点y轴的坐标
            double y = rh;
            System.out.println("x=" + x + ",y=" + y + ",rw=" + rw + ",rh=" + rh);
            StdDraw.filledRectangle(x, y, rw, rh);
        }
    }

在main方法中调用上面的方法,会展示下面的视图:

本道题的解决如下:

    /**
     * solution 
     * @param N the numbers of intervals 
     * @param l interval left value
     * @param r interval right value
     * @param a double stream
     */
    public static void histogramSolution(int N, double l, double r, double[] a){
        // double stream的组距
        Arrays.sort(a);
        double interval = (r -l) / N;
        // histogram 的组距
        double histogramInterval = 1.0 / N;
        
        for (int i = 0; i < N; i++) {
            // double stream 组距左边的值
            double dsLeft = interval * i + l;
            // double stream 组距右边的值
            double dsRight = interval * (i+1) + l;
            // 矩形中心位置x轴的坐标
            double x = histogramInterval *i +histogramInterval / 2;

            // 频次,代表直方图的高
            int countTemp = 0;
            for (int j = 0; j < a.length; j++) {
                // 频次
                if (a[j] > dsLeft && a[j] < dsRight ) {
                    countTemp ++;
                }
            }
            double p = (countTemp * 1.0) / a.length;
            //double p = (countTemp * 1.0) / N;
            // 矩形中心位置y周的坐标
            double y = p / 2;
            StdDraw.filledRectangle(x, y, histogramInterval / 2, y);
        }
    }

比如,用main方法模拟调用:

    public static void main(String[] args) {
        //barChart();
        // represent argument N
        int N = 3;
        // represent argument l
        // represent argument r
        double l = 1.09;
        double r = 23.32;
        // represent double stream
        double[] a = {1.08, 1.21, 2.33, 3.35, 8.78, 6.98, 7.99, 10.21, 15.22, 21.23, 14.51, 16.77, 18.23};
        histogramSolution(N, l, r, a);
    }

展示的结果如下:

猜你喜欢

转载自blog.csdn.net/hefrankeleyn/article/details/86549950
今日推荐