题目理解

求一个字符串(可能包含空格)中给定字母出现的次数,其中字母大小写视为同一个字母。

方法一

使用getline()函数进行整行的字符串读入。

从左到右遍历字符串,比较每个字符与给定字符是否相同。对于字母的大小写问题,我们取得对应的ASCII值,比较差的绝对值是否为32。

具体代码如下:

#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    char c;
    int count=0;
    getline(cin, s);
    cin>>c;
    for (int i=0;i<s.size();i++)
    {
        if (s[i]==c || abs((int)s[i]-(int)c)==32) count++;
    }
    cout<<count;
    return 0;
}

时间复杂度:O(N)O(N)。遍历了一遍字符串。
空间复杂度:O(1)O(1)。没有使用新的空间。

方法二

使用unordered_map这一数据结构,在读入的同时,当前字符对应map值加1。最后输出给定字母大小写对应的count之和。注意在使用while读入时,给定字符多加了一次,所以最后还要减1。示意图如下: alt

具体代码如下:

#include<iostream>
#include<string>
#include<unordered_map>

using namespace std;

int main()
{
    string s;
    char c;
    unordered_map<char,int> count;//记录每个字符出现的次数
    while(cin>>c)
    {
        count[c]++;
    }
    //给定的字符在while中多计算了一次,要减1。
    if ('A'<=c && c<='Z') cout<<count[c]+count[(int)c+32]-1;
    else cout<<count[c]+count[(int)c-32]-1;
    return 0;
}

时间复杂度:O(N)O(N)。需要遍历一遍字符串。
空间复杂度:O(1)O(1)。使用了一个unordered_map类型来记录每个字符出现的次数,最多有26个key,是常数的。