原文地址:http://blog.csdn.net/tigerisland45/article/details/70216402
问题链接:POJ2136 Vertical Histogram。
问题简述:参见上述链接。
问题分析:统计四行输入的大写字母,根据统计结果输出柱状图。
该问题的关键是需要一定的想象力,将统计数据转换成相应的图形。
需要注意的一点是,如果出现次数最多字符的出现次数为max,则输出max行。这是关键的地方。
程序说明:
(略)。
AC的C++语言程序如下:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
/* POJ2136 Vertical Histogram */
#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
using namespace std;
const int MAXN = 26;
int acount[MAXN];
int main()
{
int linecount, max;
string s;
memset(acount, 0, sizeof(acount)); //数组清零
linecount = 0;
while (getline(cin, s)) {
// 统计字母
for(int i=0; i<(int)s.size(); i++)
// if(isalpha(s[i]))
// acount[s[i] - 'A']++;
if(isupper(s[i]))
acount[s[i] - 'A']++;
// 每4行输出一次结果 即每四行进行一次统计
if(++linecount == 4) {
linecount = 0;
// 计算最大的统计值
max = 0;
for(int i=0; i<MAXN; i++)
if(acount[i] > max)
max = acount[i];
// 输出max行
for(int i=max; i>0; i--) {
for(int j=0; j<MAXN; j++) {
if(acount[j] >= i)
//acount[j] >= i , i是输出直方图的第i层,account[j]为第j个字母的个数 ;若acount[j] >= i,则表明
//第j个字母的出现个数大于等于i,因此第i层应该显示为“*”号。
cout << "* ";
else
cout << " ";
}
cout << endl;
}
for(int i=0; i<MAXN; i++)
cout << (char)('A' + i) << " ";
cout << endl;
}
}
return 0;
}
代码分析:问题的两个要素:
一是如何对输入的四行进行统计个数。二是统计得到每个字母的次数后如何输出直方图 。
对于第一点,getline(cin, s)读取一行,然后利用计数器linecount 计数,每统计完4行后就进行一次输出直方图的操作。对于每一行的统计,采用了字母ASCII码值与统计个数映射的方式,存放在数组中,如acount[s[i] - ‘A’]++。
第二点是如何进行直方图的输出。观察图像的输出格式有如下特点:①直方图的高度等于所有字母中最大的出现次数。②直方图横坐标是按照字母顺序进行输出的。代码中利用了这两个特征,先找出所有字母中最大的出现次数,然后在根据横坐标字母的出现次数判断在某个高度这个字母是否出现,显然当出现次数大于等于这个高度时,则此层应该出现“*”号,否则为空格。