题目描述

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

输入描述:

共 2 行。
第 1 行为一个字符串,其中只含字母,表示给定单词;
第 2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章

输出描述:

一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 0 开始);如果单词在文章中没有出现,则直接输出一个整数 -1。

示例1

输入
To
to be or not to be is a question
输出
2 0
说明
输出结果表示给定的单词 To 在文章中出现两次,第一次出现的位置为0。

示例2

输入
to
Did the Ottoman Empire lose its power at that time
输出
-1
说明
表示给定的单词 to 在文章中没有出现,输出整数-1。

解答

这个题目是一个字符串的综合题,在读入就有坑,第一行key单词后面的"\n"一定要处理掉,本人使用了两次读入,在读取第二行时就会将第一次读取的覆盖。 偷懒了很多天以后,决定将cin改为两个getline,提高代码可读性。
1、void convert(string test);函数用来将所有的字符全部改变成小写字符,看不懂就该看看书了哈;

2、题目本身不难,重点是要考虑到边界的处理,比如: i 和 mpi 这种是不匹配的,但是用搜索单个字母是很容易会计算进去,因为你的条件设定的不合理。

3、针对第一词出现的位置,利用变量demo来记录,所以只要flag不等于0,就说明第一词尚未出现,demo=i;继续改变demo,直到flag > 0,说明第一词已经出现,就不用改变demo了,需要关注位置从零开始的哈~

if(flag == 0){demo = i;}

3、我是这么做的,条件循环(data[i] != '\0')来完成对第二行data的搜索,然后就用条件判断(key[j] == data[i] )来判断第一个字符是否匹配,如果匹配,我就来检测(data[i+1] ==空格/或者是结束符 and key[j+1]==结束符),如果key后一项是结束符,并且data下一项为空格,说明两个单词完全相等,判断data下一项是不是结束符,非常有必要,否则就会读取非法内存!!!这个是核心。

4、要注意,我们是以核心来单词为单位来判断,所以一旦key和data的某一个单词不匹配,你应该跳过该单词剩下的所有字母,使用while(data[i++] != ' ' && data[i] != '\0'){} 来跳过剩下的字母,直到遇到空格或者data的最后一项,不能忘记j=0,key也要从头开始检测。

5、最后输出的时候检测flag,如果flag==0;表示没有匹配的单词,输出-1;否则就输出flag(次数)+ 空格+demo(第一词的位置); 大家加油~

代码:
#include <iostream>
#include <string>
using namespace std;
void convert(string &p);
int main(void)
{
    string key;
    string data;
    int flag = 0;
    int demo = -1;
    getline(cin,key);
    getline(cin,data);
    convert(data);
    convert(key);
    int i = 0; int j = 0;
    while(data[i] != '\0')
    {
        if(flag == 0)
        {
            demo = i;
        }
        while(data[i] == key[j])
        {
            if(key[j+1] == '\0' && (data[i+1] == ' ' || data[i+1] == '\0'))
            {
                flag++;
                break;
            }
            else
            {
                j++;
                i++;
            }
        }
        j = 0;
        while(data[i++] != ' ' && data[i] != '\0')
        {
        }
    }
    if(flag != 0)
        cout << flag << " " << demo;
    else
        cout << -1;
    return 0;
}
void convert(string &p)
{
    int i = 0;
    while(p[i] != '\0')
    {
        if(p[i] >= 'A' && p[i] <= 'Z' )
            p[i] += 32;
        i++;
    }
}


来源:今A