C/C++ 信奥(普及组)统计单词数

推荐刷题网站IP: 47.108.154.71

题目描述

       一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
      现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同,如果给定单词仅是文章中某一单词的一部分则不算匹配。

思路:

首先当我们读到一个题时要首先思考这道题最中心,最关键的地方在哪里,就比如这道题的关键在于给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配, 所以这道题就是让我们在不区分大小写的情况下统计出现位置出现次数,思路有了拿我来慢慢看;

题解 

我们看,题目要求我们不区分大小写,可以,你赖皮我也赖皮,我把所有的数组元素全部都转换成小写或者大写字母来进行判断和比较(这里我们全部转换成小写字母)注意:大写与小写字母在ascll码值中的差是32

string s,t;
getline(cin,t);
getline(cin,s);
s1=s.size();
t1=t.size();
for(int i=0;i<t1;++i)//题目要求不区分大小写字母,所以我们统一将字母全部转换成为小写字母方便下面计算
{
if(t[i]>=65&&t[i]<90)t[i]+=32;
//65——90是ascll值中的大写A——Z,大写和小写字母相差32所以如果t[i]中的字母是大写那么就+=32
}

for(int i=0;i<s1;++i)//题目要求不区分大小写字母,所以我们统一将字母全部转换成为小写字母方便下面计算
{
if(s[i]>=65&&s[i]<90)s[i]+=32;
//65——90是ascll值中的大写A——Z,大写和小写字母相差32所以如果s[i]中的字母是大写那么就+=32
}

我们接着想,题目要求我们是判断一部分的大小写相同不,所以我们就将那一部分的单词来进行判断,但是,我们要判断的那一部分单词前后都有字符,十分影响我们的判断,于是我们接可以有一个十分鸡贼的想法————把它们隔开。将一部分内容前后用空格隔开,单独把他揪出来来判断,也就是关 门 打 狗,代码实现如下;
t=' '+t+' ';//题目要求我们是判断一部分的大小写相同 所以我们就将那一部分的单词的前后加空格
s=' '+s+' ';//现在t的前后都已经加上了空格,但是会出现一种情况,及第一个单词的也就是数组下标0的前面还会加上一个空格,和数组的最后一个单词后面 也会加上一个空格,这样显然不对,所以后就用可以把s数组的前后也肩上一个空格来避免这种情况

接下来就是这次代码的关键所在了

首先我们来了解一下find

在使用系统自身佩戴函数的时候头文件就需要注意,必须使用

#include<stdlib.h> //或者万能头文件
#include<bits/stdc++.h>

string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数)

这个时候我们就可以来找出现次数和出现位置了;

定义一个int类型的变量用来记录字母在母串中的位置,当然是在不等于NPOS的情况底下

如代码所示:

int w=0,ans=0;
while(w!=s.npos)//在s数组不等于npos时,也就是系统找到了字母在母串中的位置(下标记录)时
{
w=s.find(t,w);//把w的值给赋值成为字母在母串中的下标

接下来就是判断了

当然在做这道题时一切的判断和循环条件都是find函数找到了字符在母串中的位置时,也就是返回值不等于npos的时候,也就是找到了在母串的位置的时候

int w=0,ans=0;
while(w!=s.npos)//在s数组不等于npos时,也就是系统找到了字母在母串中的位置(下标记录)时
{
w=s.find(t,w);//把w的值给赋值成为字母在母串中的下标
if(w!=s.npos)
{
ans++;//来统计出现次数的变量
重点 w++;//w++ w是控制循环循环的次数和控制判断数组位置的一个变量,所以每当循环完成一次我们将w++也就是从下一个位置开始判断,而不是一直判断现在的数组
}
}
int k=s.find(t);//定义一个整型变量k并且复制成为s数组中t在母串中的下标
if(k!=s.npos)//在s数组不等于npos时,也就是系统找到了字母在母串中的位置(下标记录)时
{
cout<<ans<<endl;//输出以前的计数器ans
cout<<k;
}
else
cout<<"-1";

现在来看一下这段代码较为核心的一段代码(第8行)w++

我们现在的循环判断一个位置上的字符,而w则是整串循环判断一个起到关键作用的变量,那,我们为什么要++呢?

实际上这个循环判断是在一直判断某一个位置上面的字符是否满足条件,而w则是来控制判断位置的一个整型变量,w决定我们是在判断哪一个字符的位置,++则是让w从下一个位置上的字符开始判断,而不是一只判断现在所在的字符

全代码:

#include<bits/stdc++.h>
using namespace std;
int s1=0,t1=0;
int main()
{
string s,t;
getline(cin,t);
getline(cin,s);
s1=s.size();
t1=t.size();
for(int i=0;i<t1;++i)//题目要求不区分大小写字母,所以我们统一将字母全部转换成为小写字母方便下面计算
{
if(t[i]>=65&&t[i]<90)t[i]+=32;
//65——90是ascll值中的大写A——Z,大写和小写字母相差32所以如果t[i]中的字母是大写那么就+=32
}

for(int i=0;i<s1;++i)//题目要求不区分大小写字母,所以我们统一将字母全部转换成为小写字母方便下面计算
{
if(s[i]>=65&&s[i]<90)s[i]+=32;
//65——90是ascll值中的大写A——Z,大写和小写字母相差32所以如果s[i]中的字母是大写那么就+=32
}
t=' '+t+' ';//题目要求我们是判断一部分的大小写相同 所以我们就将那一部分的单词的前后加空格
s=' '+s+' ';//现在t的前后都已经加上了空格,但是会出现一种情况,及第一个单词的也就是数组下标0的前面还会加上一个空格,和数组的最后一个单词后面 也会加上一个空格,这样显然不对,所以后就用可以把s数组的前后也肩上一个空格来避免这种情况
int w=0,ans=0;
while(w!=s.npos)//在s数组不等于npos时,也就是系统找到了字母在母串中的位置(下标记录)时
{
w=s.find(t,w);//把w的值给赋值成为字母在母串中的下标
if(w!=s.npos)
{
ans++;//ans是来统计出现次数的变量
w++;//w++ w是控制循环循环的次数和控制判断数组位置的一个变量,所以每当循环完成一次我们将w++也就是从下一个位置开始判断,而不是一直判断现在的数组
}
}
int k=s.find(t);//定义一个整型变量k并且复制成为s数组中t在母串中的下标
if(k!=s.npos)//在s数组不等于npos时,也就是系统找到了字母在母串中的位置(下标记录)时
{
cout<<ans<<endl;//输出以前的计数器ans
cout<<k;
}
else
cout<<"-1";
return 0;
}

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值