洛谷 P1308 统计单词数
- 题意:【有坑!标注重点!】给出一个单词,再给出一串文本,问单词在文本中出现的次数以及首次出现的位置。其中,大小写可以无障碍匹配(也就是要求我们要转换为全部小写)。其次,必须是文本中的独立单词才作数!也就是说:如果给定单词仅是文本中某一单词的一部分则不算匹配!
思路
- 就是裸裸的KMP模板。首先将单词文本全部转换小写字符。然后就开始KMP。需要注意的是独立单词的条件,所以一旦匹配我们还需要判断子串是不是在文本中的独立单词,如果是则说明是独立单词。
OS: 这道题竟然用不了gets()和strlwr()!!!!!会CE. 真的好迷啊。真的好迷。TAT
AC CODE
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1000000 + 7;
int Next[15];
void GetNext(string t, int len)
{
int i = 0, j = -1;
Next[0] = -1;
while(i < len)
{
if(j == -1 || t[i] == t[j])
{
++i; ++ j;
if(t[i] == t[j]) Next[i] = j;
else Next[i] = Next[j];
} else j = Next[j];
}
}
struct node{
int num, pos;
};
node KMP(string s, int s_len, string t, int t_len)
{
GetNext(t, t_len);
int i = 0, j = 0;
node ans = {0, 0};
while(i < s_len && j < t_len)
{
if(j == -1 || s[i] == t[j]) { ++i; ++ j; }
else j = Next[j];
if(j == t_len)
{
if(!isalpha(s[i]) && (i - t_len - 1 == -1 || !isalpha(s[i - t_len - 1])))
{
if(!ans.num) ans.pos = i - t_len;
++ ans.num;
}
j = Next[j];
}
}
return ans;
}
//char s[maxN], t[15];
string s, t;
int main()
{
// gets(t); gets(s);
// strlwr(t); strlwr(s);
getline(cin, t); getline(cin, s);
int s_len = s.size();
for(int i = 0; i < s_len; i ++ ) {if(s[i] >= 'A' && s[i] <= 'Z') s[i] += 'a' - 'A';}
int t_len = t.size();
for(int i = 0; i < t_len; i ++ ) {if(t[i] >= 'A' && t[i] <= 'Z') t[i] += 'a' - 'A';}
node ans = KMP(s, s_len, t, t_len);
if(ans.num == 0) printf("-1\n");
else printf("%d %d\n", ans.num, ans.pos);
return 0;
}
/*
to
to toupi usndto to you be
*/