引理:当计算第 \(i\) 位的失配指针时,若 \(j_0\) 是一个候选条件,那么小于 \(j_0\) 的最大候选条件是 \(fail[j_0]\)。

证明:反证法。假设存在 \(j_1\),使得\(fail[j_0]<j_1<j_0\),那么\(s[1,j_0]=s[i-j_0+1,i],s[i,j_1]=s[i-j_1+1,i],s[j_0-j_1+1,j_0]=s[i-j_1+1,i]\),可知\(s[1,j_1]=s[j_0-j_1+1]\),根据\(fail[\ ]\)数组的极大性可知产生了矛盾,证毕。

时间复杂度为\(O(n)\)

代码如下

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std; int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
string s, t;
cin >> s >> t;
int n = s.size(), m = t.size();
vector<int> fail(m, -1);
auto getfail = [&]() {
for (int i = 1, j = -1; i < m; i++) {
while (j != -1 && t[j + 1] != t[i]) {
j = fail[j];
}
if (t[j + 1] == t[i]) {
++j;
}
fail[i] = j;
}
};
getfail();
auto match = [&]() {
for (int i = 0, j = -1; i < n; i++) {
while (j != -1 && t[j + 1] != s[i]) {
j = fail[j];
}
if (t[j + 1] == s[i]) {
++j;
}
if (j == m - 1) {
cout << i - m + 2 << endl;
}
}
};
match();
for (auto v : fail) {
cout << v + 1 << " ";
}
cout << endl;
return 0;
}

最新文章

  1. [其他]Ubuntu安装genymotion后unable to load VirtualBox engine
  2. 25个实用的jquery技巧
  3. javafx之CSS初探
  4. android 怎么动态设置button 的style
  5. LeetCode(5) - Longest Palindromic Substring
  6. php29号小结(隔行换色&#183;&#183;&#183;&#183;&#183;&#183;)
  7. BI的核心价值[转]
  8. SQL 错误1418
  9. Python调用C可执行程序(subprocess) 分类: python 服务器搭建 C/C++ shell 2015-04-13 21:03 87人阅读 评论(0) 收藏
  10. 如何查看jar包的版本号?
  11. 查看ORACLE中正在运行的存储过程 kill
  12. HDU 3641 Treasure Hunting(阶乘素因子分解+二分)
  13. 认识J2SE
  14. Map和Collection
  15. Backup &amp;recovery备份和还原
  16. TCHAR和CHAR类型的互转,string 转lpcwstr
  17. 【题解】Luogu P2157 [SDOI2009]学校食堂
  18. MacBook小技巧
  19. mysql用户权限管理的问题
  20. 单向可控硅(SCR)双向可控硅(TRIAC)

热门文章

  1. 如何手动写一个Python脚本自动爬取Bilibili小视频
  2. Linux服务器性能压力测试
  3. Redis常用操作-------Hash(哈希表)
  4. cocoapod Podfile use frameworks swift/oc混编 could not build module xxx
  5. 最好使用%f输出浮点数据,acm
  6. 2016.3.24 OneZero站立会议
  7. Sprint 冲刺第三阶段第3-5天
  8. 四则运算-ppt演示
  9. js和JQuery区别
  10. Java使用HTTPClient3.0.1开发的公众平台消息模板的推送功能