C语言统计用户输入数字频率 垂直直方图打印空白问题求助
解决垂直直方图空白问题的分析与修复
嘿,我来帮你捋捋这个问题!你说水平直方图能正常运行,但垂直版本却输出空白,这大概率是两个地方出了问题——其中统计频率的代码没过滤非数字字符是导致空白的核心原因,垂直直方图的逻辑也有可以优化的地方。
先拆解问题:
1. 核心问题:统计代码越界访问,破坏了频率数据
你当前的统计代码里,只要输入不是EOF就直接执行++a[c-'0'],但如果输入了空格、换行、字母这类非数字字符,c-'0'会算出负数或者大于9的数(比如空格的ASCII是32,32-48=-16),这就会越界访问数组a(它的合法下标只有0-9)。越界访问会破坏内存里的其他数据,很可能把你原本正确统计的频率值冲成0或者乱码,这样垂直直方图自然打印不出内容。
2. 次要问题:垂直直方图逻辑不够合理(还修改了原数组)
你原来的垂直直方图代码里,判断a[j]==i才打印*,然后把a[j]减1。这个逻辑虽然能凑出结果,但一来会把原数组的频率值全改成0,没法复用;二来如果输入的最大频率小于10,前面的行会全是空格,观感也很差。
修复后的完整代码
先把统计代码改成只处理数字字符:
int a[10]; // 存储0-9的出现频率 int c; // 接收getchar的输入值 int i; // 循环变量 // 初始化数组为0 for(i = 0; i < 10; i++) { a[i] = 0; } // 仅统计输入中的数字字符 while((c = getchar()) != EOF) { // 判断是否为0-9的数字 if(c >= '0' && c <= '9') { ++a[c - '0']; } }
然后重新编写垂直直方图的逻辑,这次我们先找到最大频率确定打印行数,而且不修改原数组:
// 先找出最大频率,确定需要打印的行数 int max_freq = 0; for(i = 0; i < 10; i++) { if(a[i] > max_freq) { max_freq = a[i]; } } // 从上到下打印垂直直方图 for(i = max_freq; i > 0; i--) { int j; for(j = 0; j < 10; j++) { // 只要当前数字的频率大于等于当前行号,就打印* if(a[j] >= i) { printf("*\t"); } else { printf("\t"); // 否则打印空白占位 } } printf("\n"); } // 最后打印底部的数字标签 printf("0\t1\t2\t3\t4\t5\t6\t7\t8\t9\n");
测试示例
比如你输入112223333,统计后a[1]=2、a[2]=3、a[3]=4,其他为0,输出会是:
* * * * * * * * * * * 0 1 2 3 4 5 6 7 8 9
这样就完全正常了,不会再出现空白的情况。
内容的提问来源于stack exchange,提问作者SARTHAK MEHRA
相关产品推荐
相关产品推荐

