[NOIP2011]统计单词数

[NOIP2011]统计单词数

https://ac.nowcoder.com/acm/problem/16585

分析

首先分别将两个字符串输入

std::getline(std::cin, p);
std::getline(std::cin, s);

分别小写化,使用tolower函数将字符串的每一个字符变成小写。

遍历字符串s

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

利用s[i]与p首字母进行匹配,不匹配的情况不能进入循环。

若匹配,则逐字符匹配,同时声明两个变量,m, n分别记录s和p的位置,但是不改变i的大小。

int m = i, n = 0;
while (s[m] == p[n] && p[n]) //p[n]表示p最后一个字母用完跳出
{
    m++, n++;
}

累加不匹配就跳出。

如果p还没有遍历完就跳出,在s[i]与p首字母匹配前定义一个变量fff记录p是否用完。

fff = ( p[n] )? 0 : 1;

如果p遍历完了,就让结果加1。

note: 结尾应该是空格或者'\0',才能证明完全匹配。

if (fff) {
    if (s[m] != ' ' && s[m] != '\0') continue;
    if (ans == 0) {
        pos = i; //pos记录首次匹配位置
    }
    ++ans;
    i += len_p;//完全匹配字母已经遍历完了,直接跳过,减少重复遍历。
}

note: 刚才是结尾是空格,但是突然发现上面的程序并不能通过。

例如:

t
tt t

我的输出

3 0

而正确输出

1 3

note: 接上面note,不仅结尾是空格,而且开头是空格。

在这种情况下,如果首字母匹配,前一个字符是空格,可以继续遍历,如果不是,说明它也不可能是匹配,因为i += len_p;//完全匹配字母已经遍历完了,直接跳过,减少重复遍历。在根据if (s[m] != ' ' && s[m] != '\0') continue;说明不匹配的刚刚跳出,所以我需要继续往后走,直到走到空格。

if (s[i - 1] >= 'a' && s[i - 1] <= 'z') {
    while (s[i] >= 'a' && s[i] <= 'z') {
        i++;
    }
}

完整代码:

#include <iostream>
#include <ctype.h>
#include <algorithm>
#include <string>

int main()
{
    std::string p, s;
    std::getline(std::cin, p); std::getline(std::cin, s);
    int len_p = p.length();
    int len_s = s.length();
    
    for (int i = 0; p[i]; i++)
    {
        p[i] = tolower(p[i]);
    }
    for (int i = 0; s[i]; i++)
    {
        s[i] = tolower(s[i]);
    }

    //std::cout << p << "\n";
    //std::cout << s << "\n";
    int pos, ans = 0;
    for (int i = 0; i < len_s; ++i) {
        int fff = 0;
        if (s[i] == p[0]) {
            if (s[i - 1] >= 'a' && s[i - 1] <= 'z') {
                while (s[i] >= 'a' && s[i] <= 'z') {
                    i++;
                }
            }
            int m = i, n = 0;
            while(s[m] == p[n] && p[n]) {
                m++,n++;
            }
            //std::cout << n << " " << int( p[n] ) << "\n";
            fff = ( p[n] ) ? 0 : 1;
            if (fff) {
                if (s[m] != ' ' && s[m] != '\0') continue;
                if (ans == 0) {
                    pos = i;
                }
                ans++;
                i += len_p;
            }
        }
    }

    if (ans > 0) {
        std::cout << ans << " " << pos;
    }
    else {
        std::cout << "-1";
    }

    return 0;
}
全部评论
这家伙还以为自己很nb呢
点赞 回复
分享
发布于 2022-01-14 23:26

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务