题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087
题目大意:给定字符串 (s) 和 (t) ,找出 (s) 中出现不重叠的 (t) 的最多次数。
举个例子,(s) 串为 "abababa" , (t) 串为 "aba" ,虽然 (s[0..2]、s[2..4]、s[4..6]) 都为 "aba" ,但是如果都选出了的话,会有重叠部分,所以最多的方案是找到 (s[0..2]、s[4..6]) 这两个,是不重叠的。
题目分析:如果是要找 (s) 中所有的所有的 (t) 的话,每当找到的时候,会将 (j) 置为 (nxt[j]) ,那这里因为是需要不重叠,所以每当找到的时候,将 (j) 置为 (-1) ,就可以保证 (s) 中每个匹配子串的空间不重叠了。
实现代码如下:
#include <cstdio>
#include <string>
using namespace std;
const int maxn = 1001000;
int T, n, m, nxt[maxn], ans;
string s, t; // s代表母串,t代表子串
char ch[maxn];
string read() {
scanf("%s", ch);
string tmp_s = ch;
return tmp_s;
}
void cal_next() {
m = t.length();
for (int i = 0, j = -1; i < m; i ++) {
while (j != -1 && t[j+1] != t[i]) j = nxt[j];
nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1;
}
}
void find_s_has_distinct_t_count() {
ans = 0, n = s.length(), cal_next();
for (int i = 0, j = -1; i < n; i ++) {
while (j != -1 && t[j+1] != s[i]) j = nxt[j];
if (t[j+1] == s[i]) {
j ++;
if (j >= m-1) {
ans ++;
j = -1;
}
}
}
printf("%d
", ans);
}
int main() {
while (true) {
s = read();
if (s == "#") break;
t = read();
find_s_has_distinct_t_count();
}
return 0;
}
作者:zifeiy