题目描述
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1 ),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2 )。
输入格式
共2行。
第1行为一个字符串,其中只含字母,表示给定单词;
第2行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从0 开始);如果单词在文章中没有出现,则直接输出一个整数−1。
输入1
To
to be or not to be is a question
输出 1
2 0
输入 2
to
Did the Ottoman Empire lose its power at that time
输出 2
-1
思路:
这题确实对于我自己来说比较难,看了视频才感觉会了一点点,感觉这个题得拆着走,才能完好的执行下去,下面我分步骤进行解释
1.首先先对输入的变量,进行定义,然后进行输入。
char word[100];
char sentence[1000010];
gets(word);gets(sentence);
//值得注意的是这里不能用cin,因为cin遇到空格就熄火了,所以这里用gets比较好
//输入完后,打印一下看看自己输入的有没有问题 cout << word << sentence << endl;没问题就进行下一步
2.由于是不区分大小写的,在执行的过程中难以直接进行转换,我们就得转换思路,遇到这种变化的,我们一开始就全部转成固定的,也就是将输入的单词和句子全部转换为小写,这样就后面就好执行了。
既然要转换,那么就必定要两个字符串的长度,然后进行for循环来转换
int lword = strlen(word);
int lsentence = strlen(sentence);
for (int i = 0; i < lword; i++)
{
if (word[i] >= 'A' && word[i] <= 'Z')
{
word[i] += 32;//大写转换为小写的办法
}
}
for (int j = 0; j < lsentence; j++)
{
if (sentence[j] >= 'A' && sentence[j] <= 'Z')
{
sentence[j] += 32;//大写转换为小写的办法
}
}
3.大小写转换完成后,就要开始执行了,思路是从句子中,每次记录下单词的开始坐标和结束坐标,然后与单词进行比较,比较成功就sum++,然后记录下第一次比对成功的坐标即可,下面贴上完整代码,代码注释有详细的解释
#include<iostream>
#include<cstdio>
using namespace std;
#include<string.h>
int main()
{
char word[100];
char sentence[1000010];
gets_s(word); gets_s(sentence);
//值得注意的是这里不能用cin,因为cin遇到空格就熄火了,所以这里用gets比较好
//输入完后,打印一下看看自己输入的有没有问题 cout << word << sentence << endl;
//2.由于是不区分大小写的,在执行的过程中难以直接进行转换,我们就得转换思路,遇到这种变化的.
//我们一开始就全部转成固定的,也就是将输入的单词和句子全部转换为小写,这样就后面就好执行了
//既然要转换,那么就必定要两个字符串的长度,然后进行for循环来转换
int lword = strlen(word);
int lsentence = strlen(sentence);
int x, y;
for (int i = 0; i < lword; i++)
{
if (word[i] >= 'A' && word[i] <= 'Z')
{
word[i] += 32;//大写转换为小写的办法
}
}
for (int j = 0; j < lsentence; j++)
{
if (sentence[j] >= 'A' && sentence[j] <= 'Z')
{
sentence[j] += 32;//大写转换为小写的办法
}
}
int sum = 0,index=-1;//sum为单词匹配的总数,index为第一个单词出现的坐标
for (int i = 0; i < lsentence; i++)//完整循环句子
{
if (i == 0 || sentence[i -1] == ' ')//只有当当前的位置为第一个,或者上一个为空格的时候。
//那么这个位置就是句子中单词的开始位置
{
x = i;//跳出来后,用x记录下开始的位置
while (i < lsentence && sentence[i] != ' ')i++;//不断循环这个单词,i不断++,直到遇到空格
y = i;//y记录的就是空格的位置
//此时已经录下来了一个单词
//然后和word进行比较
if (y - x == lword)//如果长度相等,再进行比较,免得浪费
{
bool flag = 1;//先将flag置为1,如果下面遇到不匹配的那么flag自然会变成0
for (int j = x; j < y ; j++)//循环从x到y,因为y的位置为单词后面的空格,所以不需要循环到y
{
if (sentence[j] != word[j - x])//当匹配中遇到不相同的,flag置为0,同时跳出循环
{
flag = 0;
break;
}
}
//如果一直匹配成功,上面的if不会执行,flag仍然是1,执行下面的代码
if (flag)//flag为1,证明if里面没有运行,每个字符都是相同的
{
sum++;//相同的次数+1;
if(index == -1)//如果这里不加上这个条件,那么如果后面有的单词匹配成功了,会覆盖第一次的坐标
index = x;//将第一次出现的坐标赋值给index,因为要记录第一次出现的坐标
}
}
}
}
//循环完成后应该是差不多了
if (sum > 0)cout << sum << " " << index;
else cout << -1 << endl;
return 0;
}