# 菜鸟的coding · Day 017
废话
题目
小R每天对小J滔滔不绝,小J想证明小R说的内容都是重复的废话。给定一段只含英文字符和数字的字符串(可能含空格),统计数字 0-9 和字母 A-Z(大小写不区分)各出现多少次,并画出柱状统计图。
输入:共1行,一个字符串,字符数量不超过1000个。
输出:一个柱状图,每格用空格隔开,* 表示该字符有计数,- 表示没有,最后一行为标签 0 1 2 ... 9 A B ... Z。
样例:
输入
I1think2programming3is4something5that6allows7me8to9achieve0a!great@sense#of$accomplishment.
输出
- - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - - * - - - * - - - - - - - - - - * - - - - - - - - - - - - - - - - * - - - * - - - * - - - * - * - - - * * - - - - - - - - - - - - - - - - * - - - * - - * * - - - * * * - - - * * - - - - - - - - - - - - - - - - * - - - * - * * * - - - * * * - - - * * - - - - - - - - - - - - - - - - * - * - * - * * * - - * * * * - - * * * - - - - - - - - - - - - - - - - * - * - * - * * * - - * * * * * - * * * - - - - - - * * * * * * * * * * * - * - * * * * * - * * * * * * - * * * - * * - - - 0 1 2 3 4 5 6 7 8 9 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
思路
用 getline 读整行字符串(因为可能含空格)。遍历每个字符,用 isdigit 和 isalpha 判断类型——注意判断的是字符 s[c],而不是循环索引 c——将结果累计到 cnt[36]:数字映射到下标 s[c]-'0',字母先 toupper 再映射到 toupper(s[c])-'A'+10。
统计完后找最大值 maxVal,再倒序从第 maxVal 行到第 1 行输出:内层循环遍历 36 列,cnt[列] >= 当前行 输出 *,否则输出 -,每格后跟一个空格。最后一行直接输出固定标签。
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin,s);
int cnt[36]={0};
for(int c=0;c<s.size();c++){
if(isdigit(s[c])){
cnt[s[c]-'0']++;
}else if(isalpha(s[c])){
cnt[toupper(s[c])-'A'+10]++;
}
}
int maxVal=0;
for(int c=0;c<36;c++){
if(cnt[c]>maxVal)maxVal=cnt[c];
}
for(int c1=maxVal;c1>0;c1--){
for(int c2=0;c2<36;c2++){
if(cnt[c2]>=c1)cout<<"* ";
else cout<<"- ";
}
cout<<endl;
}
cout<<"0 1 2 3 4 5 6 7 8 9 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"<<endl;
return 0;
}
复杂度分析
- 时间复杂度:O(n + maxVal × 36),n 为字符串长度,输出部分最多 1000 × 36 次。
- 空间复杂度:O(1),cnt 数组固定大小 36。
今日感受
看起来复杂的题,拆开来一步步做也不难。有一个容易踩的坑:用 isdigit 和 isalpha 判断时,传入的应该是字符 s[c],而不是循环索引 c——索引只是个数字,字符才是真正要判断的内容。输出部分记得倒序遍历行,从最高处往下画才能得到正确的柱状图。