基于字母频率数组绘制直方图的实现求助
实现字母频率直方图打印
你已经完成了字母频率统计的核心逻辑,接下来要实现直方图打印,核心思路是从频率最高的行开始,逐行向下遍历,每个字母若当前行在它的频率范围内就打印*,否则打印空格,最后补充分隔线和字母行即可。
步骤拆解
- 先找出频率数组中的最大值,确定需要打印的总行数
- 从最高频率行开始,逐行递减到第1行
- 每行遍历26个字母,判断当前字母的频率是否大于等于当前行号,是则输出
*,否则输出空格,每个字符间留空格保证对齐 - 最后打印分隔线和a-z的字母行
完整代码实现
把你的drawHistogram()方法补充完整,优化后的代码如下:
void drawHistogram() { int[] frequency = new int[26]; // 你已实现的频率统计逻辑,这里做了简化优化 for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (Character.isLetter(c)) { // 转小写后减去'a'的ASCII值,直接得到0-25的索引,比getNumericValue更直观 int index = Character.toLowerCase(c) - 'a'; frequency[index] += 1; } } // 1. 找出最大频率,确定直方图的总行数 int maxFreq = 0; for (int count : frequency) { if (count > maxFreq) { maxFreq = count; } } // 2. 从最高行开始逐行打印 for (int row = maxFreq; row > 0; row--) { for (int i = 0; i < 26; i++) { // 当前字母频率 >= 当前行号时打印*,否则打印空格 System.out.print(frequency[i] >= row ? "* " : " "); } System.out.println(); // 每行结束换行 } // 3. 打印分隔线 System.out.println("---------------------------------------------------"); // 4. 打印a-z字母行 for (char c = 'a'; c <= 'z'; c++) { System.out.print(c + " "); } System.out.println(); }
关键说明
- 优化了频率索引计算:
Character.toLowerCase(c) - 'a'替代原有的getNumericValue逻辑,直接利用ASCII值差得到0-25的索引,更易懂且不易出错 - 逐行打印逻辑:比如示例中最大频率是3,就从第3行开始打印,只有频率≥3的字母(l、o)会显示
*;第2行则显示频率≥2的字母(e、i、v、l、o),以此类推,形成从上到下递减的直方图 - 空格对齐:每个字符后加空格,保证直方图和下方的字母行完全对齐,视觉更规整
测试效果
当text = "I love problem-solving."时,运行方法会输出和你示例完全一致的结果:
* * * * * * * * * * * * * * * * * * * --------------------------------------------------- a b c d e f g h i j k l m n o p q r s t u v w x y z
内容的提问来源于stack exchange,提问作者BetaChad
相关产品推荐
相关产品推荐

