统计字符
1 条题解
-
0
P4653 统计字符(入门)
解题思路
第一步,明确题目要什么。 题目给了一串只由小写字母组成的字符串,要统计 a 到 z 每个字母各出现了多少次。
第二步,开一个计数器数组。 我们开一个长度为 26 的数组 letterCnt,约定 letterCnt[0] 表示字母 'a' 的个数,letterCnt[1] 表示 'b' 的个数,……,letterCnt[25] 表示 'z' 的个数。
第三步,学会"字符变下标"的魔法。 用 str[i]-'a' 就可以把字母变成数组下标。比如字符 'c','c'-'a'=2,所以它应该加到 letterCnt[2] 上。遍历字符串的每一个字符,找到对应的下标加 1,统计就完成了。这样我们不需要去记 ASCII 码的具体数值,用减法一切就变得很自然。
第四步,按顺序输出。 把 letterCnt[0] 到 letterCnt[25] 按顺序输出,中间用空格隔开,一共 26 个整数。
第五步,用样例验证。 拿样例 "abbcccxyz" 来说:a 出现 1 次,b 出现 2 次,c 出现 3 次,x、y、z 各出现 1 次,其他字母都是 0 次。所以输出第一项是 1,第二项是 2,第三项是 3,中间是一长串 0,最后是 1 1 1,和样例完全一致。
第六步,处理空输入的边界情况。 如果输入的字符串是空的,程序应该什么都不输出,直接结束。代码中先把字符数组初始化为空,再用 cin>>str 的返回值判断读取是否成功:如果读取失败就直接返回,不输出任何内容。这样即使评测数据里出现空串,程序也不会乱输出东西,更不会访问到未初始化的数组内容。学会处理边界情况,是写程序时很重要的能力,很多同学就是栽在没考虑空输入上。
参考代码
// P4653 统计字符:统计字符串中 a~z 每个字母出现的次数 #include <iostream> using namespace std; char str[1005] = ""; int letterCnt[26]; int main() { if (!(cin >> str)) return 0; // 输入为空时直接结束,不输出任何内容 for (int i = 0; str[i] != '\0'; i++) letterCnt[str[i] - 'a']++; for (int i = 0; i < 26; i++) { if (i > 0) cout << " "; cout << letterCnt[i]; } cout << endl; return 0; }复杂度分析
只需要从头到尾扫描一次字符串,时间 O(len),len 最大 1000;输出固定是 26 个数。空间上只用一个 letterCnt[26] 数组,是 O(1)。无论怎么算都非常快。
- 1