在java中将水平星号直方图翻转为垂直直方图

dpiehjr4  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(329)

我试图从水平直方图创建一个垂直直方图。我已经尝试过类似的嵌套循环设置,但我似乎无法做到这一点,而不打破代码。我正在慢慢地从课本上学习,所以我只对有限的函数有过经验。
在垂直图形中使用空格进行缩放比我所能处理的要困难得多。

public static void main(String atgs[]) {
    int[] distribution = {0,1,8,59,215,703,1848,3975,8077,13937,22195,31628,
                        41711,51099,57142,59959,59670,55756,48850,40931,32583,
                        24995,18217,12794,8623,5577,3601,2272,1259,764,464,246,
                        153,80,39,22,12,6,3,0};

    final int MAX_COUNTS = distribution.length;

    System.out.println(String.format("%3s %-11s %-11s %-11s %-11s %-11s %-11s %-11s", " ", "0", "10000", "20000", "30000", "40000", "50000", "60000"));
    System.out.println("    -----------------------------------------------------------------------------");
    System.out.println(String.format("%3s %-11s %-11s %-11s %-11s %-11s %-11s %-11s", " ", "|", "|", "|", "|", "|", "|", "|"));

    for (int i = 0; i < MAX_COUNTS; i++) {
        if (i % 10 == 0) {
            System.out.print(String.format("%3s %-1s", String.valueOf(i), "|"));

            int n = distribution[i] / 1000 + 1;
            for (int j = 1; j <= n; j++) {
                System.out.print(String.format("%1s", "*"));
            }
            System.out.println();
        } else {
            System.out.print(String.format("%-3s %-1s", " ", "|"));
            int n = distribution[i] / 1000 + 1;
            for (int j = 1; j <= n; j++) {
                System.out.print(String.format("%1s", "*"));
            }
            System.out.println();
        }
    }
}
k5ifujac

k5ifujac1#

创建垂直直方图比创建水平直方图更复杂。
以下是您的分布数组的结果。

60,000- |                                                                                 
          |                               * *                                               
          |                             * * *                                               
          |                             * * * *                                             
          |                             * * * *                                             
  50,000- |                           * * * * *                                             
          |                           * * * * * *                                           
          |                           * * * * * *                                           
          |                           * * * * * *                                           
          |                           * * * * * *                                           
  40,000- |                         * * * * * * * *                                         
          |                         * * * * * * * *                                         
          |                         * * * * * * * *                                         
          |                         * * * * * * * *                                         
          |                         * * * * * * * * *                                       
  30,000- |                       * * * * * * * * * *                                       
          |                       * * * * * * * * * *                                       
          |                       * * * * * * * * * *                                       
          |                       * * * * * * * * * * *                                     
          |                     * * * * * * * * * * * *                                     
  20,000- |                     * * * * * * * * * * * *                                     
          |                     * * * * * * * * * * * * *                                   
          |                     * * * * * * * * * * * * *                                   
          |                     * * * * * * * * * * * * *                                   
          |                   * * * * * * * * * * * * * * *                                 
  10,000- |                   * * * * * * * * * * * * * * *                                 
          |                 * * * * * * * * * * * * * * * * *                               
          |                 * * * * * * * * * * * * * * * * *                               
          |                 * * * * * * * * * * * * * * * * * *                             
          |               * * * * * * * * * * * * * * * * * * * * *                         
       0- | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - 
          0                  10                  20                  30

我做的最大的“把戏”是把垂直直方图颠倒过来。换句话说,我首先创建了x轴标签线,然后是虚线,然后是自下而上的直方图线。我把所有的台词都存了起来 java.util.List ,然后按相反顺序打印输出行。
我将代码分解为七个方法,不包括 main 方法。我这样做是为了一次只关注垂直直方图的一部分。
我并不是一下子写下所有这些代码的。我一次画一条垂直直方图。我首先构建了垂直直方图,然后添加了y轴标签。我做了测试。我可能在完成代码之前运行了50-70个测试。
我用了一个 StringBuilder 建造每一条线。你可以连接 String 分段在一起,但是 StringBuilder 效率更高。
以下是完整的可运行代码。我希望你检查代码,并试图了解我做了什么。

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

public class VerticalHistogram {

    public static void main(String atgs[]) {
        VerticalHistogram vh = new VerticalHistogram();

        int[] distribution = { 0, 1, 8, 59, 215, 703, 1848, 3975, 8077, 
                13937, 22195, 31628, 41711, 51099, 57142, 59959,
                59670, 55756, 48850, 40931, 32583, 24995, 18217, 
                12794, 8623, 5577, 3601, 2272, 1259, 764, 464, 246,
                153, 80, 39, 22, 12, 6, 3, 0 };
            vh.createVerticalHistogram(distribution);
    }

    private NumberFormat numberFormat;

    public VerticalHistogram() {
        this.numberFormat = NumberFormat.getIntegerInstance();
    }

    public void createVerticalHistogram(int[] distribution) {
        int maximum = calculateMaximum(distribution);
        maximum = roundUp(maximum, 1000);

        // 30 is maximum height of histogram
        int interval = maximum / 30; 
        int labelInterval = interval * 5;
//      System.out.println(maximum + " " + interval);

        List<String> output = generateVerticalHistogram(distribution, 
                interval, labelInterval, maximum);
        for(int i = output.size() - 1; i >= 0; i--) {
            System.out.println(output.get(i));
        }
    }

    private int calculateMaximum(int[] distribution) {
        int max = distribution[0];

        for (int i = 1; i < distribution.length; i++) {
            max = Math.max(max, distribution[i]);
        }

        return max;
    }

    private List<String> generateVerticalHistogram(int[] distribution, 
            int interval, int labelInterval, int max) {
        List<String> output = new ArrayList<>();
        output.add(generateXLabels(distribution));
        output.add(generateXAxis(distribution));

        for (int value = interval; value <= max; value += interval) {
            output.add(generateYValue(distribution, value, labelInterval));
        }

        return output;
    }

    private String generateXLabels(int[] distribution) {
        StringBuilder builder = new StringBuilder();
        builder.append("          ");

        for (int i = 0; i < distribution.length; i++) {
            if (i % 10 == 0) {
                builder.append(i);
            } else {
                builder.append("  ");
            }
        }

        return builder.toString();
    }

    private String generateXAxis(int[] distribution) {
        StringBuilder builder = new StringBuilder();
        builder.append("       ");
        builder.append(numberFormat.format(0));
        builder.append("- ");

        for (int i = 0; i < distribution.length; i++) {
            if (i % 5 == 0) {
                builder.append("| ");
            } else {
                builder.append("- ");
            }
        }

        return builder.toString();
    }

    private String generateYValue(int[] distribution, int value, 
            int labelInterval) {
        StringBuilder builder = new StringBuilder();
        if (value % labelInterval == 0) {
            String label = numberFormat.format(value);
            int margin = 8 - label.length();
            for (int i = 0; i < margin; i++) {
                builder.append(" ");
            }
            builder.append(label).append("- | ");
        } else {
            builder.append("          | ");
        }

        for (int i = 0; i < distribution.length; i++) {
            if (distribution[i] >= value) {
                builder.append("* ");
            } else {
                builder.append("  ");
            }
        }

        return builder.toString();
    }

    private int roundUp(int max, int factor) {
        return (max + factor - 1) / factor * factor;
    }

}

相关问题