题目的主要信息:

  • 输入一个由字母、数字、空格组成的字符串,和一个目标字符,求该目标字符在字符串中出现的次数
  • 不区分字母大小写

方法一:哈希表

具体做法:

我们可以按字符遍历输入的字符串,然后用无序哈希表记录每个字符出现的频率,因为不区分大小写,我们就将全部大写字母转换为相应的小写字母再统计。统计完成,输入目标字符,如果是大写字符将其转化成小写以后再进入哈希表查找出现的次数。

alt

#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(n)O(n),遍历字符串的每个字符
  • 空间复杂度:O(1)O(1)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)O(n),相当于遍历字符串的所有字符
  • 空间复杂度:O(n)O(n)O(n),数组要存储字符串所有的非空格字符