字符串匹配のKMP【专题@AbandonZHANG】
#include
#include
#include
#include
using namespace std;const int N = 1000100;
string A, B;
int pi[N];void getp()
{memset(pi,0,sizeof(pi));int m = B.length();pi[0] = -1;int j = -1;for (int i = 1;i < m; i ++){while(j > -1 &&B[j+1] != B[i]) j = pi[j];if (B[j+1] == B[i]) j++;pi[i] = j;}
}
int kmp()
{int res = 0;getp();int n = A.length();int m = B.length();int j = -1;for (int i = 0; i < n; i ++){while(j > -1 && A[i] !=B[j+1]) j = pi[j];if (A[i] == B[j+1]) j++;if (j == m - 1){res ++;j = pi[j];}}return res;
}
int main()
{int tt;scanf("%d",&tt);while (tt--){cin>>B;cin>>A;cout<♦POJ 1226 Substrings (最长公共子串。KMP + 二分)数据范围很小,随便搞吧?=。=。其实就是二分答案长度,枚举出该长度的每一个串,然后用KMP验证。总复杂度O(n*len2*log(len))吧,可以接受的。但是我怎么可以这么弱?各种小错误啊调试了2个小时了吧靠靠靠靠这么个水题。。。。。。
#include
#include
#include
#include
using namespace std;char s[110][110];
char p[110];
int pi[110];
void getpi()
{int m = strlen(p);int j = -1;pi[0] = -1;for (int i = 1; i < m; i ++){while(j > -1 && p[j+1] != p[i]) j = pi[j];if (p[j+1] == p[i]) j++;pi[i] = j;}
}
bool kmp(int x)
{getpi();int n = strlen(s[x]);int m = strlen(p);int j = -1;for (int i = 0; i < n; i ++){while(j > -1 && s[x][i] != p[j+1]) j = pi[j];if (s[x][i] == p[j+1]) j++;if (j == m - 1){return true;}}return false;
}
int BS(int n)
{if (n == 1) return strlen(s[0]);int h = 0, t = strlen(s[0]) + 1;while(h <= t){memset(p,0,sizeof(p));int fg = 1;int mid = (h + t) >> 1;for (int i = 0; i < strlen(s[0]) - mid + 1; i ++){if (fg == n) break;else fg = 1;for (int k = 1; k < n; k ++){for (int j = 0; j < mid; j ++)p[j] = s[0][i + j];if (kmp(k)) fg++;else{for (int j = 0; j < mid; j ++)p[mid - j - 1] = s[0][i + j];if (kmp(k)) fg++;else break;}}}if (fg == n)h = mid + 1;else t = mid - 1;}return h - 1;
}
int main()
{int t;scanf("%d",&t);while(t--){memset(p,0,sizeof(p));int n;scanf("%d",&n);for (int i = 0; i < n; i ++)scanf("%s",s[i]);printf("%d\n",BS(n));}return 0;
}
♦POJ 2406 Power String (最小周期(重复)子串。加深对next函数的理解) 首先要理解next数组表示的是字符串前缀的“对称”程度。 然后记住这个结论:对于一个字符串s,如果len是(len - next[len])的倍数,那么len - next[len]就是s的最小周期子串。 证明一下(解释不太清楚>.<……):如果len是len-next[len]的倍数,假设m = len-next[len] ,那么str[1-m] = str[m-2*m],……,以此类推下去,m肯定是str的最小重复单元的长度。假如len不是len-next[len]的倍数, 如果前缀和后缀重叠,那么最小重复单元肯定str本身了,如果前缀和后缀不重叠,那么str[m-2*m] != str[len-m,len],所以str[1-m] != str[m-2*m] ,最终肯定可以推理出最小重复单元是str本身,因为只要不断递增m证明即可。 还是自己在纸上好好推演一下比较好。
#include
#include
#include
using namespace std;const int N = 1000010;
int pi[N];
char p[N];int getpi()
{int m = strlen(p);pi[0] = -1;int j = -1;for (int i = 1; i < m; i ++){while(j > -1 && p[j+1] != p[i]) j = pi[j];if (p[j+1] == p[i]) j++;pi[i] = j;}int x = m - 1 - pi[m - 1];if (m % x == 0)return x;else return m;
}int main()
{while(scanf("%s",p)!=EOF){if (p[0] == '.') break;int l = strlen(p);printf("%d\n",l / getpi());}return 0;
}
♦HDU 3336 Count the String (KMP+DP) 问题抽象:求所有前缀在字符串中出现的次数。 暴力枚举会达到O(n3)是不行的,枚举前缀然后KMP也会达到O(n2)。当然对于前缀的情况我们应该利用好“前缀数组”------next数组。实际上现在很多题也都不是考KMP而是考next数组的灵活运用。(KMP裸模板题有什么好考的。。。) 我们把问题分成几个子问题来看,用DP解决:f[i]表示以第i位为结尾的字符串匹配数。则sum = ∑f[i] 。 怎么利用next数组呢?我们知道next[i] = j表示串B[1...j] == B[i-j+1...i],那么一部分串(B[i-j+1...i]的后缀串)与前缀的匹配是可以通过j来求出来的,因为相等关系,所以这部分f[i]等价于f[next[i]]。这只是一部分以i结尾的啊,那么以[1...i-j]某处开头、以 i 结尾的串有没有可能呢?答案是不可能的,如果与前缀匹配成功那么next[i]就不是j了(想想是不是~),当然要加上他本身(B[1..i])是整个串前缀的情况,所以得出f[i] = f[next[i]] + 1。然后再算出sum就行了~~~
#include
#include
#include
#include
using namespace std;const int N = 200010;
string s;
int f[N],pi[N];
void getpi()
{int m = s.length();pi[0] = -1;int j = -1;for (int i = 1; i < m; i ++){while(j > -1 && s[j+1] != s[i]) j = pi[j];if (s[j+1] == s[i]) j++;pi[i] = j;}
}
int ff()
{getpi();int sum = 1;int m = s.length();f[0] = 1;for (int i = 1; i < m; i ++){f[i] = f[pi[i]] + 1;sum += f[i];sum %= 10007;}return sum;
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);cin>>s;printf("%d\n",ff()%10007);}return 0;
}
(未完待续。。。)
转载于:https://www.cnblogs.com/AbandonZHANG/archive/2012/10/23/4113948.html
字符串匹配のKMP【专题@AbandonZHANG】相关推荐
- 字符串匹配KMP算法
字符串匹配KMP KMP过程其实就是去找下一个更好的状态的过程,省略去了中间穷举的无用过程,直接跳到下一个更好的状态,通过模式串本身的信息,站在模式串的角度来考虑问题 取长的一对 若想让模式串直接从S ...
- kmp算法详解php,php中字符串匹配KMP算法实现例子
KMP算法是一个比较高级的算法了,加了改进了,下面我们来在php中实现KMP算法,希望例子对各位同学会带来帮助哦. kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J. ...
- C++实现字符串匹配KMP算法
文章目录 1. 概述 2. 代码实现 3. 代码测试 1. 概述 Kmp算法的介绍及思想参阅下面两篇文章: 字符串匹配KMP算法 算法)通俗易懂的字符串匹配KMP算法及求next值算法 2. 代码实现 ...
- 字符串匹配 KMP算法
问题描述:字符串匹配即查找待匹配字符串(模式串)p在主串s中的位置.一般处理这种问题往往采用简单粗暴的方法--暴力匹配法.所谓暴力匹配法,就是对主串s的每一个字符与要匹配的字符串p的每个字符进行逐一匹 ...
- 字符串匹配——KMP算法
字符串匹配--KMP算法 字符串匹配是计算机编程中最常使用到的基础算法之一.字符串匹配相关的算法很多,Knuth-Morris-Pratt(KMP)算法是最常用的之一.最近在学习KMP算法,学习了 ...
- 字符串匹配のKMP【@Abandon】
算法详解 很长时间内都没有能够很理解KMP算法的精髓,尤其是很多书上包括<算法导论>没有把next函数(亦或 π函数)讲解的很透彻. 今天去看了matrix67大牛博客中关于kmp部分的讲 ...
- C语言实现字符串匹配KMP算法
相信很多人(包括自己)初识KMP算法的时候始终是丈二和尚摸不着头脑,要么完全不知所云,要么看不懂书上的解释,要么自己觉得好像心里了解KMP算法的意思,却说不出个究竟,所谓知其然不知其所以然是也. 字符 ...
- [JAVA][算法] [字符串匹配]KMP
我们为什么需要KMP? 在字符串匹配问题中,我们需要找到匹配串pattern在原串text中的位置,一种显而易见的思路就是暴力匹配,如图所示,我们把pattern放置到text中的每个位置进行比较即可 ...
- 字符串匹配KMP算法的讲解C++
转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...
最新文章
- 为什么UI线程中创建Handler可以不传Looper?
- View_01_LayoutInflater的原理、使用方法
- Redis设计与实现阅读总结(二)单机数据库的实现
- java 页面 分离 实现_JavaBean实现JSP页面和代码分离
- ubuntu “快捷方式”
- 八. 输入输出(IO)操作6.文件与目录管理
- opencv yuv保存本地_OpenCV-dlib-python3实现人脸戴墨镜和含Y的抖音效果
- Linux系统openssl升级,在Linux系统上升级OpenSSL的方法
- 多学一招总没错吧?SpringBoot解决前后端分离的跨域问题
- JAVA 实现FTP功能_在Java程序中实现FTP功能
- Broadcom fullmac WLAN 驱动解析(1)
- 中国磷矿市场趋势报告、技术动态创新及市场预测
- Spring学习02-Spring中的设计模式(一)
- 太湖2018年渔业产值达7.3亿元 今年大闸蟹产量将降低
- 【米哈游】2022春季校园招聘
- c++重载运算符实现分数加减乘除
- 成为网络工程师后具体的工作内容的问题
- 面试题:1000瓶酒找1瓶毒酒
- word文件的打开密码如何破解
- FOSS社区可以拯救197种濒临灭绝的印度语言吗?
热门文章
- 小学文凭有计算机知识,重大版小学信息技术毕业复习题
- python中re模块怎么导入_python如何导入re模块
- python判断对错题_python 初学者错题本
- 【干货】Linux 运维故障排查思路,有这篇文章就够了
- vue展示日历 考勤展示_VUE实战—菜单栏商品展示数据交互(8)
- 1 分钟 Serverless 极速抽盲盒,自己部署自己抽
- 如何在工作中快速成长?致工程师的 10 个简单技巧
- ggplot2设置坐标轴范围_ggplot2画图时出现重合的点以及标签如何处理?有现成的包ggrepel
- 三级计算机系统是什么情况,三级PC技术: 计算机的组成和分类
- jsp mysql驱动程序_JSP通过JDBC驱动MySQL数据库方法