2.26 统计字符串字母,单词个数,并找出出现最多次数字母

该博客讨论了一个编程问题,要求统计不区分大小写的英文句子中的字母个数、单词个数,并找出出现频率最高的字母及其次数。作者提到了两种不同的解决方案,一种是使用自定义Record结构体和vector,另一种是利用ASCII码值存储数据。博客强调了审题的重要性,特别是在编程挑战中避免错误。

题目描述:

从键盘输入一行英文句子,句子中只有英文单词和空格,每个单词之间由若干个空格隔开, 英文单词由大小写字母组成,编程完成下列任务:

(1)统计并输出此句子中英文字母的个数; (10 分)
(2)统计并输出此句子中单词的个数; (10 分)
(3)查找此句子中出现次数最多的字母(不区分大小写,大小写字母是相同的)和次数。 当出现最多的字符不止一个时,都能找到,并输出找到的所有字母及次数。(输出字母时大小写 均可) (20 分)

例如:
输入

This is An Pencil Case

输出

字母个数:18
单词个数:5
最多的字母:i,s
出现的次数:3

这题有一个地方我开始没看到,就是不区分大小写,这就使我开始写的代码在统计时区分了大小写,既然如此,就分别考虑,两种情况吧!

当不区分大小写时:

1.我用的vector容器,自定义一个Record结构体,记录字符c和次数num
2.用暴力的方法,从头开始扫描,每扫描一个单词,就进入二层循环,扫描后面的单词是否有相同的,相同计数加1,且标记为‘#’,代表已经扫描,后面再遇到时就跳过

代码:

typedef struct Record{
    char c;
    int num;
    Record(char a,int b):c(a),num(b){}
}Record;

int main(){
    string s;
    getline(cin,s);

    vector<Record> vec;
    int whitenum=0;
    int letternum=0;
    int iflastwhite=1;

    for(int i=0;i<s.length();i++){

        if(s[i]==' '){
            whitenum++;
            iflastwhite=1;
        }else if(s[i]=='#'){
            if(iflastwhite==1){
            letternum++;
                iflastwhite=0;
            }
            continue;

        }else{
            if(iflastwhite==1){
                letternum++;
                iflastwhite=0;
            }

            int sum=1;
            for(int j=i+1;j<s.length();j++){
                if(s[j]!='#'&&s[j]!=' '&&s[i]==s[j]){
                    sum++;
                    s[j]='#';
                }
            }

            Record rec(s[i],sum);
            vec.push_back(rec);
        }
    }

    int maxnum=0;
    for(int i=0;i<vec.size();i++){
        if(vec[i].num>maxnum){
            maxnum=vec[i].num;
        }
    }

    cout<<"字母个数:"<<letternum<<endl;
    cout<<"单词个数:"<<s.length()-whitenum<<endl;
    cout<<"出现最多的字母:";
    int j=0;
    while(vec[j].num!=maxnum) j++;
    cout<<vec[j].c;
    for(int i=j+1;i<vec.size();i++){
        if(vec[i].num==maxnum){
            cout<<","<<vec[i].c;
        }
    }

    cout<<endl;
    cout<<"出现最多的次数:"<<maxnum;

}

当不区分大小写时:

很明显我上面的方法已经没有用了,于是改成了依据字母的ASCII码值存储数据
1.定义一个数组num[26],用字母的顺序来存储
2.扫描每个字母,分别是对应的下标加1

int main(){
    string s;
    getline(cin,s);

    int num[26]={0};
    int whitenum=0;
    int letternum=0;
    int iflastwhite=1;

    for(int i=0;i<s.size();i++){

        if(s[i]==' '){
            whitenum++;
            iflastwhite=1;
        }else{
            if(iflastwhite==1){
                letternum++;
                iflastwhite=0;
            }

            int index=s[i]>='a'?s[i]-'a':s[i]-'A';
            num[index]++;

        }
    }

    int maxnum=0;
    for(int i=0;i<26;i++){
        if(num[i]>maxnum){
            maxnum=num[i];
        }
    }

    cout<<"字母个数:"<<letternum<<endl;
    cout<<"单词个数:"<<s.length()-whitenum<<endl;
    cout<<"出现最多的字母:";
    int j=0;
    while(num[j]!=maxnum) j++;
    cout<<char('a'+j);

    for(int i=j+1;i<26;i++){
        if(num[i]==maxnum){
            cout<<','<<char(i+'a');
        }
    }


    cout<<endl;
    cout<<"出现最多的次数:"<<maxnum;


}

小结:
审题一定要认真的,复试的时候可不能出差错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值