XTU OJ Diagram

 

图表

题目描述

给你一个字符串,请统计各个字符出现的个数,并使用字符打印一幅统计图表。

图表的格式是

  1. x轴是字符,y轴是字符出现个数
  2. x轴的字符为字符串中出现过的字符,并按字典顺序排列
  3. y轴中的出现次数使用'*'表示。为了让图表不至于太长,一个'*'表示的数量要尽可能的大。
  4. 每行的行末不允许多余的空格。

输入

存在多个测试用例,处理到文件末尾。
每行一个只含英文大写字母的字符串,长度不超过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');
	}
}

动动小手点个赞🥧吧~~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值