【问题标题】:Histogram from grade array list in JavaJava中成绩数组列表的直方图
【发布时间】:2015-11-12 04:49:07
【问题描述】:

我正在尝试从包含学生成绩的 arrayList 制作直方图。我已经进行了如下所示的成绩细分:

/**
 * Returns a simple, 5-element array with the counts for each of the letter grades,
 * (A, B, C, D, and F), based on the 10-point scale
 * @return 5-element array
 */
private int[] calculateGradingBreakdown() {
    int[] breakdown;
    breakdown = new int[7];
    for (Student kids: this.students) {
        int grade = kids.getNumericGrade();
        if (grade >= 90) {
            breakdown[0] += 1;
        } else if (grade >= 80) {
            breakdown[1] += 1;
        } else if (grade >= 70) {
            breakdown[2] += 1;
        } else if (grade >= 60) {
            breakdown[3] += 1;
        } else {
            breakdown[4] += 1;
        }
    }
    return breakdown;
}

/**
 * Returns a string that lists the grade letter and the count of students
 * receiving the grade on the roster
 * @return grade breakdown
 */
public String getGradeBreakdown() {
    String gradeBreakdown = null;
    int[] breakdown = this.calculateGradingBreakdown();
    gradeBreakdown = ("A: " + breakdown[0] + "\nB: " + breakdown[1] + "\nC: " + breakdown[2]
            + "\nD: " + breakdown[3] + "\nF: " + breakdown[4]);
    return gradeBreakdown;
}

我的直方图代码已经更改了几次,但需要包含下面列出的方法。我已将当前代码保留在其中,但正在努力解决如何使直方图按所列方式工作。

/**
 * Accepts a number of stars (*) to be created, creates a String with that
 * number of *'s side-by-side, and then returns that string.
 */
private String makeStarRow(int number) {
    int[] breakdown = this.calculateGradingBreakdown();
    number = breakdown[];
    String stars = 
}

/**
 * Returns a string holding a horizontal histogram of *'s
 */
public String getGradeHistogram() {
    String gradeHistogram = null;
    int[] breakdown = this.calculateGradingBreakdown();
    gradeHistogram = (this.makeStarRow(breakdown[0]));
    gradeHistogram += (this.makeStarRow(breakdown[1]));
    gradeHistogram += (this.makeStarRow(breakdown[2]));
    gradeHistogram += (this.makeStarRow(breakdown[3]));
    gradeHistogram += (this.makeStarRow(breakdown[4]));

    return gradeHistogram;
}   

成绩分类和直方图的输出应如下所示(数字根据另一个班级的输入):

A: 2
B: 2
C: 2
D: 0
F: 1

**
**
**

*

【问题讨论】:

  • 那么问题是什么?如何实现makeStarRow()?您的 javadoc 说明了一切。照它说的去做。

标签: java arrays arraylist histogram


【解决方案1】:

为了您的兴趣和参考,这里有一个使用 Java 8 流的解决方案:

void printHistogram(List<Integer> scores) {
    scores.stream().collect(Collectors.groupingBy(n -> n < 60 ? 5 : n / 10));
        .entrySet().stream().sorted(Map.Entry::comparingByKey)
        .map(entry -> entry.getValue().size());
        .map(size -> Stream.iterate(() -> "*").limit(size).collect(Collectors.joining()))
        .forEach(System.out::println);
}

【讨论】:

    【解决方案2】:

    创建重复符号字符串的一种方法是使用Arrays.fill

    private String makeStarRow(int number) {
        char[] starChars = new char[number];
        Arrays.fill(starChars, '*');
        String stars = new String(starChars) + '\n';
        return stars;
    }
    

    请注意,根据getGradeHistogram 方法,您可能需要将'\n' 附加到星星字符串的末尾。

    【讨论】:

    • 为什么要从char[] 构建一个字符串,然后再进行字符串连接以添加一个字符?字符串连接表示new StringBuilder().append(new String(charChars)).append('\n').toString()Yikes!! 构建一个更大的数组并将最后一个字符设置为\n。或者两个更大,并将最后两个设置为 \r\n
    • @Andreas,这种优化对 OP 程序的整体性能没有任何意义,但会使其更难维护(用其他东西替换 '\n' 也需要修补数组长度)。也可以通过 JIT 追加单个字符 optimized。仍然会发生单个数组复制,但不会实际创建具有中间数组的 StringBuilder 实例。
    • @Andreas,我的基准测试表明,对于热代码,每行 1-10 颗星将节省 20 ns,每行 100 颗星将节省 200 ns。这种过早的优化不会增加将这些行打印到标准输出的应用程序。打印(甚至重定向到 nul)至少需要 100 倍以上的时间。
    【解决方案3】:

    感谢各位的帮助。我实际上得到了一个可行的解决方案:

    /**
     * Accepts a number of stars (*) to be created, creates a String with that
     * number of *'s side-by-side, and then returns that string.
     */
    private String makeStarRow(int number) {
        while (number > 0) {
            System.out.print("*");
            number--;
        } 
        if (number < 1) {
            System.out.println();
        }
        return null;
    }
    
    /**
     * Returns a string holding a horizontal histogram of *'s
     * @return histogram
     */
    public String getGradeHistogram() {
        int[] histogram = this.calculateGradingBreakdown();
        for (int xi = 0; xi < this.students.size(); xi++) {
            int meh = histogram[xi];
            this.makeStarRow(meh);
        }
        return "";
    }   
    

    它会打印出我正在寻找的内容。希望这对将来的某人有所帮助。

    答:2

    B:2

    C: 2

    D: 0

    F: 1

    **

    **

    **

    *

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      相关资源
      最近更新 更多