题目的主要信息:
- 输入一个由字母、数字、空格组成的字符串,和一个目标字符,求该目标字符在字符串中出现的次数
- 不区分字母大小写
方法一:哈希表
具体做法:
我们可以按字符遍历输入的字符串,然后用无序哈希表记录每个字符出现的频率,因为不区分大小写,我们就将全部大写字母转换为相应的小写字母再统计。统计完成,输入目标字符,如果是大写字符将其转化成小写以后再进入哈希表查找出现的次数。
#include<iostream>
#include<unordered_map>
using namespace std;
int main(){
char target;
unordered_map<char, int> mp;
char c;
while((c = getchar()) != '\n'){ //按字符输入字符串
if(c >= 'A' && c <= 'Z') //大写转小写
c = c - 'A' + 'a';
mp[c]++; //统计频率
}
cin >> target; //输入目标字符
if(target >= 'A' && target <= 'Z') //大写转小写
target = target - 'A' + 'a';
cout << mp[target] << endl;
return 0;
}
复杂度分析:
- 时间复杂度:O(n),遍历字符串的每个字符
- 空间复杂度:O(1),哈希表大小为字符集,我们这里只有小写字母、空格、数字,因此是常数空间
方法二:遍历统计法
具体做法:
我们可以用一个vector数组来记录cin读取的字符串,以空格分开作为单词(因为空格不会是目标字符)。需要注意这种读取方***将目标字符读取成数组的最后一个字符,我们要将其提取出来,后续遍历的时候也要去掉这个。
然后我们遍历刚刚得到的字符串数组,用方法一相同的大写转换小写的方式,然后比较是否相同,相同则记录出现的频数,最后输出即可。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
vector<string> s;
string input;
while(cin >> input) //将字符串以空格分割作为单词保存在数组
s.push_back(input);
char target = s[s.size() - 1][0]; //第二行输入的目标字符也会被上方代码读取,数组最后一个字符串就是目标字符
if(target >= 'A' && target <= 'Z') //大写转小写
target = target - 'A' + 'a';
int res = 0;
for(int i = 0; i < s.size() - 1; i++){ //遍历数组的每个字符
for(int j = 0; j < s[i].length(); j++){
char c = s[i][j];
if(c >= 'A' && c <= 'Z') //大写转小写
c = c - 'A' + 'a';
if(c == target) //记录出现次数
res++;
}
}
cout << res << endl;
return 0;
}
复杂度分析:
- 时间复杂度:O(n),相当于遍历字符串的所有字符
- 空间复杂度:O(n),数组要存储字符串所有的非空格字符