【题目描述】
写一个程序从输入文件中读取四行大写字母(全都是大写的,每行不超过
100
100
100个字符),然后用柱状图输出每个字符在输入文件中出现的次数。严格地按照输出样例来安排你的输出格式。
【输入格式】
四行字符,由大写字母组成,每行不超过
100
100
100个字符
【输出格式】
由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的。在任何一行末尾不要打印不需要的多余空格。不要打印任何空行。
【输入样例】
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG.
THIS IS AN EXAMPLE TO TEST FOR YOUR
HISTOGRAM PROGRAM.
HELLO!
【输出样例】
*
*
* *
* * * *
* * * *
* * * * * *
* * * * * * * * * *
* * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
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
【分析】
首先我们要统计出每个字母出现的次数 c n t cnt cnt,并且记下出现次数的最大值 m a x v maxv maxv。
由于每行末尾不能出现多余的空格,因此我们遍历所有的出现次数 1 ∼ m a x v 1\sim maxv 1∼maxv,找到出现次数大于等于 i i i的最后一个位置 j j j,记为 l a s t [ i ] = j last[i]=j last[i]=j。
由于我们从上往下输出,因此我们从
m
a
x
v
maxv
maxv开始从大到小遍历每个出现次数
i
i
i,对于每个
i
i
i,我们再从左往右遍历每个字母
j
(
0
≤
j
≤
l
a
s
t
[
i
]
)
j(0\le j\le last[i])
j(0≤j≤last[i]),即将
A
∼
Z
A\sim Z
A∼Z映射为
0
∼
25
0\sim 25
0∼25,如果
c
n
t
[
j
]
≥
i
cnt[j]\ge i
cnt[j]≥i,那么输出*
,否则输出空格。
【代码】
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
int maxv;
int cnt[30], last[410];
string s;
int main()
{
for (int i = 0; i < 4; i++)
{
getline(cin, s);
for (int i = 0; i < s.size(); i++)
if (s[i] >= 'A' && s[i] <= 'Z') cnt[s[i] - 'A']++, maxv = max(maxv, cnt[s[i] - 'A']);
}
for (int i = 1; i <= maxv; i++)
for (int j = 0; j < 26; j++)
if (cnt[j] >= i) last[i] = j;
for (int i = maxv; i; i--)
{
for (int j = 0; j <= last[i]; j++)
{
if (cnt[j] >= i) cout << '*';
else cout << ' ';
if (j != last[i]) cout << ' ';
}
cout << endl;
}
for (int i = 0; i < 26; i++)
{
cout << (char)(i + 'A');
if (i < 26 - 1) cout << ' ';
}
return 0;
}