AcWing 446. 统计单词数(KMP找单词首次出现位置,特判单词前后空格)
原题链接
简单
作者:
Once.
,
2025-01-13 23:06:11
,
所有人可见
,
阅读 2
用KMP算法找单词首次出现位置,然后在匹配时特判单词前后空格
时间复杂度$O(n)$,$n$为文章长度
C++ 代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int ne[N];
string s, p;
int cnt, ans[N];
bool flag = true;
void to_lower(string &s) //转小写
{
for (char &x: s) x = tolower(x);
}
void strStr(string s, string p) //KMP,s为长串,p为短串
{
int n = s.size(), m = p.size();
s = ' ' + s, p = ' ' + p;
for (int i = 2, j = 0; i <= m; i++)
{
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j++;
ne[i] = j;
}
for (int i = 1, j = 0; i <= n; i++)
{
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j++;
if (j == m)
{
if (s[i + 1] != ' ') continue;//单词后空格
if (s[i - m] != ' ') continue;//单词前空格
ans[cnt++] = i - m;//记录单词出现位置
flag = false;
}
}
}
int main()
{
getline(cin, p);
getline(cin, s);
to_lower(p), to_lower(s);
strStr(s, p);
if (flag) printf("-1");
else printf("%d %d\n", cnt, ans[0]);
return 0;
}