[NOIP2011 普及组] 统计单词数的疑问

[NOIP2011 普及组] 统计单词数

题目描述

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

输入格式

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

输出格式

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

样例 #1

样例输入 #1

To
to be or not to be is a question

样例输出 #1

2 0

样例 #2

样例输入 #2

to
Did the Ottoman Empire lose its power at that time

样例输出 #2

-1

我的测评如下:

img

我的代码如下:

#include
#include
//o(10^6)
char WZ[1000001]={0};
char DC[11] = {0}, tDC[11] = {0}, s;
int main() {
    
    scanf("%s\n", &DC);
    int i = -1, cnt = 0, pCnt = 0;
    fgets(WZ,1000001,stdin);
    int lenWZ = strlen(WZ), lenDC = strlen(DC);
    //转换成小写
    for (int j = 0; j < lenDC; j++) {
        if (!(DC[j] <= 'z' && DC[j] >= 'a') && DC[j] != ' ') {
            DC[j] += 32;
        }
    }
    for (int j = 0; j < lenWZ; j++) {
        if (!(WZ[j] <= 'z' && WZ[j] >= 'a') && WZ[j] != ' ') {
            WZ[j] += 32;
        }
    }
    //复制到另一个数组再进行比较,先特判一下
    strncpy(tDC, WZ, lenDC);
    if (strcmp(tDC, DC) == 0 && WZ[ lenDC] == ' ') {
        cnt++;
    }
    for (int j = 1; j < lenWZ - lenDC + 1; j++) {
        strncpy(tDC, WZ + j, lenDC);
        if (strcmp(tDC, DC) == 0 && WZ[j - 1] == ' ' && WZ[j + lenDC] == ' ') {
            cnt++;
        }
        if (WZ[j] == ' ' && cnt == 0) {
            pCnt++;
        }
    }
    if (cnt != 0) {
        printf("%d %d\n", cnt, pCnt);
    } else {
        printf("-1\n");
    }
    return 0;
}

求神犇教教我,万分感谢!

供参考!谢谢!

img

img

img

img


#include <stdio.h>
#include <string.h>

char WZ[1000001] = {'\0'};                //改
char DC[11] = {'\0'}, tDC[11] = {'\0'}; //改
int main()
{
    int cnt = 0, pCnt = -1; //改 i是多余的删掉了

    scanf("%10[^\n^\r]s", DC); //改

    scanf(" %1000000[^\n^\r]s", WZ); //改

    int lenWZ = strlen(WZ), lenDC = strlen(DC);

    //转换成小写
    for (int j = 0; j < lenDC; j++)
    {
        if (DC[j] <= 'Z' && DC[j] >= 'A') //改
        {
            DC[j] += 32;
        }
    }
    for (int j = 0; j < lenWZ; j++) //改  用!不好理解容易预判
    {
        if (WZ[j] <= 'Z' && WZ[j] >= 'A')
        {
            WZ[j] += 32;
        }
    }

    for (int j = 0; j < lenWZ - lenDC + 1; j++)
    { //大修改
        strncpy(tDC, WZ + j, lenDC);
        if (strcmp(tDC, DC) == 0 && (WZ[j + lenDC] == ' ' || WZ[j + lenDC] == '\0'))
        {
            if (j == 0)
            {
                cnt++;
                if (cnt == 1)
                    pCnt = 0;
            }
            else if (WZ[j - 1] == ' ')
            {
                cnt++;
                if (cnt == 1)
                    pCnt = j;
            }
        }
    }

    if (cnt != 0)
    {
        printf("%d %d\n", cnt, pCnt);
    }
    else
    {
        printf("-1\n");
    }
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define M 512
#define N 20

void tolowers(char *s)
{
    while (*s != '\0')
    {
        if (isupper(*s))
            *s = tolower(*s);
        s++;
    }
}

int tj(char *s, char *word, int *index)
{
    char w[N] = {'\0'};
    char word0[N] = {'\0'};

    char *p0 = strstr(s, word);

    if (p0 == NULL)
    {
        return 0;
    }

    index[0] = 0;
    index[1] = p0 - s;

    strncpy(word0, word, strlen(word));
    tolowers(word0);

    char *p = s;

    while (*p == ' ')
        p++;
    while (*p != '\0')
    {
        sscanf(p, "%s", w);
        tolowers(w);

        if (strcmp(w, word0) == 0)
            index[0] += 1;
        p += strlen(w);
        while (*p == ' ')
            p++;
    }

    return 1;
}

int main(int argc, char *argv[])
{
    char s[M], word[N];
    int index[2];    
    
    scanf("%[^\n^\r]s", word);
    getchar();
    scanf("%[^\n^\r]s", s);

    int n = tj(s, word, index);
    if (n == 0)
        puts("-1");
    else
    {
        printf("\n%d %d\n", index[0], index[1]);
    }
}