图表
题目描述
给你一个字符串,请统计各个字符出现的个数,并使用字符打印一幅统计图表。
图表的格式是
- x轴是字符,y轴是字符出现个数
- x轴的字符为字符串中出现过的字符,并按字典顺序排列
- y轴中的出现次数使用'*'表示。为了让图表不至于太长,一个'*'表示的数量要尽可能的大。
- 每行的行末不允许多余的空格。
输入
存在多个测试用例,处理到文件末尾。
每行一个只含英文大写字母的字符串,长度不超过1000。输出
每行输出一个样例的结果,每个结果之后有一个空行。
样例输入
AABBCC AAAABBBBCC AABBBBDDDE样例输出
*** ABC ** *** ABC * ** *** **** ABDE提示
第一个样例,ABC都是出现2次,所以我们可以用一个星号表示出现2次。
第二个样例的第一行坐标C的位置是行末,没有空格,是回车。ABC分别出现4,4,2次,所以使用一个星号表示出现2次
第三个样例没有C字符,所有没有C字符的统计信息。第1,2行的A字符位置是空格。
这道题是标准的打印题,我的分析都在注释里面了 (很详细哟)
#include <stdio.h>
#include <string.h>
char m[1011][27];
int gcd(int x, int y) {
return y ? gcd(y, x % y) : x;
}
//最大公约数函数若是其中一个为0,则返回的值即为另一个传入值
//根据这个性质,反复求gcd时,我们便不需要对之初始化
int main() {
char s[1001], *p;/*使用指针进行递增,不用指针似乎在空间时间上都没有太大的变化*/
//显然使用指针更为简便
while (gets(s)) {
int cnt[26] = {0}, d, i, j, col, row;
for (p = s; *p; p++)
cnt[*p - 'A']++;
for (d = 0, i = 0; i < 26; i++) d = gcd(d, cnt[i]);
for (row = col = i = 0; i < 26; i++) {
cnt[i] /= d;
if (cnt[i] > row) row = cnt[i];
}
memset(m, ' ', sizeof(m));
//打印类问题,一般来说,先将n维数组当作画板进行打印后直接输出较为简单
for (i = 0, col = 0; i < 26; i++)
if (cnt[i]) {
m[row][col] = 'A' + i;
//横坐标轴的处理
for (j = 0; j < cnt[i]; j++)
m[row - j - 1][col] = '*';
//一列一列的打印*号
//个数存储在cnt[i]中
col++;
//对于没有26个字母全部出现的情况,这里的col已经解决
}
for (i = 0; i <= row; i++) {
//输出时却换成了对每一行进行输出
for (j = col; j >= 0 && m[i][j] == ' '; j--);
//从每一行的末端向前
//找到从右往左第一个要输出 * 的位置
m[i][j + 1] = 0;/*这里的 0 指代的是 '\0' */
//将此位置后端一位安上结束符
puts(m[i]);
//由此,我们可以直接输出这一行的字符串且行末无空格
//而在此之前的空格都无需处理,我们需要将之打印出来
}
putchar('\n');
}
}
动动小手点个赞🥧吧~~~