字符串匹配-KMP
来源:互联网 发布:apache服务器搭建 编辑:程序博客网 时间:2024/06/05 18:44
#include <iostream>
#include <string>
#include <cstring>
using namespacestd;
const int maxn =10005;
int f[maxn];
void getf1(string p)//可判断周期及循环数
{
memset(f, -1,sizeof(f));
f[0] =f[1] =0;
for (int i =1; i < p.size(); i ++) {
int j =f[i];
while (j && p[i] != p[j]) {
j = f[j];
}
f[i +1] = p[i] == p[j] ? j +1 : 0;
}
for (int i =1; i <= p.size(); i ++) {
// cout << f[i] << " " ;
if (i % (i -f[i]) == 0 &&f[i] > 0) {
cout << i -f[i] << " " << i / (i -f[i]) << endl;//周期长度周期数
}
}
cout <<endl;
}//getf1()
void match1(string t,string p)
{
getf1(p);
int j =0;
for (int i =0; i < t.size(); i ++) {
while (j && t[i] != p[j]) {
j = f[j];
}
if (t[i] == p[j]) {
j ++;
}
if (j == p.size()) {
cout << i - j +1 << endl;
}
}
}//match1()
void getf3(string p)//据说省时
{
memset(f, -1,sizeof(f));
f[0] =f[1] =0;
int i =1,j = 0;
while(i < p.size()){
if (j ==0 || p[i] == p[j]) {
i ++;j ++;
if (p[i] == p[j]) {
f[i] =f[j];
}
elsef[i] = j;
}
else j =f[j];
}
}//getf3()
void match3(string t,string p)
{
getf3(p);
int i =0,j = 1;
while(i <= t.size() && j <= p.size()) {
if (j ==0 || t[i] == p[j]) {
i ++;j ++;
}
else j =f[j];
if (j == p.size()) {
cout << i - j <<endl;
}
}
}//match23()
int main()
{
string s,t;
cin >> s >> t;
getf1(s);
match1(t, s);
getf3(s);
match3(t, s);
return0;
}
KMP就像dfs,只是方法,题意变化,需要技巧转化。
poj1961
求给定字符串s,前i个字符,是否存在是字符串t的循环,循环次数k>1。求每种t的长度和k。
先求失配数组f[]。若i失配,则回到f[i],则s[f[i]..i]是s[1..i]的某个前缀,s[1..i]可能存在长度为(i - f[i])的字符串循环。
(i - f[i]) * k = i得到i % (i - f[i]) = 0。
且k > 1,即f[i] > 0。
poj2752
给定字符串s,求所有字符串a,为s的前缀后缀。即求所有k,使s[1..k] = s[sz - k + 1..sz]
失配数组f[].
q1 = f[sz],即s[1..q1] 与s[1..sz]最后q1个字符相同
q2 = f[q1],即s[1..q2] 与s[1..q1]最后q2个字符相同,即s[1..q2]与s[1..sz]最后q2个字符相同,即s[1..q2]同时为s的前缀后缀。
以此类推,至q = f[qx] = 0,没有一个字符相同,退出。
- KMP 字符串匹配算法
- kmp字符串匹配算法
- kmp字符串匹配算法
- KMP字符串匹配算法
- 字符串匹配算法-kmp
- KMP(字符串匹配)算法
- 字符串匹配 KMP
- KMP 字符串匹配算法
- 字符串匹配算法:KMP
- KMP算法 字符串匹配
- 字符串匹配 KMP 算法
- KMP字符串匹配(1)
- KMP字符串匹配(2)
- KMP字符串匹配(3)
- KMP字符串匹配算法
- KMP字符串匹配
- KMP字符串匹配算法
- KMP字符串匹配
- 动效神器 Origami Studio 汉化
- Spring Boot 运行原理
- Android CardView 和Material Design风格设计学习
- 二叉排序树的实现
- Android 利用layoutParams代码动态布局空间位置
- 字符串匹配-KMP
- 华为手机logcat不出日志解决方案
- Ubuntu
- Linux安装apache详解
- javascript第5章
- View页面间的跳转
- 解决Android Studio编译后安装apk报错:The APK file does not exist on disk
- JavaScript京东左侧控件效果
- 堆排序算法解析