字符串专题:KMP POJ 3561
http://poj.org/problem?id=3461
KMP这里讲的不错next的求法值得借鉴 http://blog.sina.com.cn/s/blog_70bab9230101g0qv.html
这道题要用到KMP,基于邝斌牌模板,复杂度O(M+N)
一开始T了,用了后缀数组,复杂度O(Nlog2n)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
#define N 100010
char s[N * ], p[N];
/*
* next[]的含义:x[i-next[i]...i-1]=x[0...next[i]-1]
* next[i]为满足x[i-z...i-1]=x[0...z-1]的最大z值(就是x的自身匹配)
*/
void kmp_pre(char x[],int m,int next[])
{
int i,j;
j=next[]=-;
i=;
while(i<m)
{
while(-!=j && x[i]!=x[j])j=next[j];
next[++i]=++j;
}
}
/*
* kmpNext[]的意思:next'[i]=next[next[...[next[i]]]] (直到next'[i]<0或者x[next'[i]]!=x[i])
* 这样的预处理可以快一些
*/
/*void preKMP(char x[],int m,int kmpNext[])
{
int i,j;
j=kmpNext[0]=-1;
i=0;
while(i<m)
{
while(-1!=j && x[i]!=x[j])j=kmpNext[j];
if(x[++i]==x[++j])kmpNext[i]=kmpNext[j];
else kmpNext[i]=j;
}
}*/
/*
* 返回x在y中出现的次数,可以重叠
*/
int next[];
int KMP_Count(char x[],int m,char y[],int n)
{
//x是模式串,y是主串
int i,j;
int ans=;
//preKMP(x,m,next);
kmp_pre(x,m,next);
i=j=;
while(i<n)
{
while(-!=j && y[i]!=x[j])j=next[j];
i++;
j++;
if(j>=m)
{
ans++;
j=next[j];
}
}
return ans;
}
int main()
{
int ncase;
int ans;
scanf("%d", &ncase);
while(ncase--)
{
scanf("%s%s", p, s);
int lens = strlen(s);
int lenp = strlen(p);
ans=KMP_Count(p,lenp,s,lens);
printf("%d\n", ans);
}
return ;
}
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int n,k,m,number;
int rank[],tmp[],sa[];
bool common_sa(int i,int j)
{
if(rank[i]!=rank[j]) return rank[i]<rank[j];
else
{
int ri=i+k<=n?rank[i+k]:-;
int rj=j+k<=n?rank[i+k]:-;
return ri<rj;
}
}
void construct_sa(string s,int *sa)
{
n=s.length();
for(int i=;i<=n;i++)
{
sa[i]=i;
rank[i]=i<n?s[i]:-;
}
for(k=;k<=m;k*=) //这里的k是递归到长度为k的串
{
sort(sa,sa+n+,common_sa);
tmp[sa[]]=;
for(int i=;i<=n;i++)
{
tmp[sa[i]]=tmp[sa[i-]]+(common_sa(sa[i-],sa[i])?:);
}
for(int i=;i<=n;i++)
{
rank[i]=tmp[i];
}
}
}
bool contain(string s,int *sa,string t)
{
int a=,b=s.length();
while(b-a>)
{
int c=(a+b)/;
if(s.compare(sa[c],t.length(),t)<) a=c;
else b=c;
}
return s.compare(sa[b],t.length(),t)==;
} int main()
{
string mode,donser;
ios::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
while(cin>>mode>>donser)
{
n=donser.size();
m=mode.size();
construct_sa(donser,sa);
if(!contain(donser,sa,mode)) cout<<""<<endl;
else
{
char c=mode[];
for(int i=;i<n;i++)
{
if(donser[i]==c)
{
int y=rank[i];number=;
for(int j=i;j<n;j++)
{
if(rank[j]==y) number++;
}
break;
}
}
cout<<number<<endl;
}
}
return ;
}
T掉的 后缀数组
后缀数组这里也有值得说的
rank数组对字串长度做1 2 4 8这样的增长式划分,划分的最大长度可以直接定为匹配串的长度,
这样根据rank数组的值和位置就能知道相同的串个数了。
字符串专题:KMP POJ 3561的更多相关文章
- LeetCode 字符串专题(一)
目录 LeetCode 字符串专题 <c++> \([5]\) Longest Palindromic Substring \([28]\) Implement strStr() [\(4 ...
- NOIP2018提高组金牌训练营——字符串专题
NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个 ...
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
- c算法:字符串查找-KMP算法
/* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...
- 字符串专题:map POJ 1002
第一次用到是在‘校内赛总结’扫地那道题里面,大同小异 map<string,int>str 可以专用做做字符串的匹配之类的处理 string donser; str [donser]++ ...
- 字符串KMP || POJ 2185 Milking Grid
求一个最小矩阵,经过复制能够覆盖原矩阵(覆盖,不是填充,复制之后可以有多的) *解法:横着竖着kmp,求最大公倍数的做法是不对的,见http://blog.sina.com.cn/s/blog_69c ...
- 并不对劲的字符串专题(二):kmp
据说这些并不对劲的内容是<信息学奥赛一本通提高篇>的配套练习. 先感叹一句<信息学奥赛一本通提高篇>上对kmp的解释和matrix67的博客相似度99%(还抄错了),莫非mat ...
- 字符串截取模板 && POJ 3450、3080 ( 暴力枚举子串 && KMP匹配 )
//截取字符串 ch 的 st~en 这一段子串返回子串的首地址 //注意用完需要根据需要最后free()掉 char* substring(char* ch,int st,int en) { ; c ...
- 字符串专题之KMP算法
写点自己对KMP的理解,我们有两个字符串A和B,求A中B出现了多少次. 这种问题就可以用KMP来求解. 朴素的匹配最坏情况是O(n^2)的.KMP是个高效的算法,效率是O(n)的. KMP算法的思想是 ...
随机推荐
- Intellij IDEA 快捷键整理(TonyCody)
[常规] Ctrl+Shift + Enter,语句完成 "!",否定完成,输入表达式时按 "!"键 Ctrl+E,最近的文件 Ctrl+Shift+E,最近更 ...
- Swift中的willSet与didSet
Swift中的willSet与didSet 周银辉 在Swift语言中用了willSet和didSet这两个特性来监视属性的除初始化之外的属性值变化 无需说太多,看看下面的代码你就能很快明白的 imp ...
- Java多线程卖票例子
package com.test; public class SaleTickets implements Runnable { private int ticketCount = 10;// 总的票 ...
- Python 从零学起(纯基础) 笔记 之 collection系列
Collection系列 1. 计数器(Counter) Counter是对字典类型的补充,用于追踪值的出现次数 ps 具备字典所有功能 + 自己的功能 Counter import col ...
- FastJson的简单实用
一.FastJson的理解 在工作中,经常客服端需要和服务端进行通信,目前很多项目都采用JSON的方式进行数据传输,简单的参数可以通过手动拼接JSON字符串,但如果请求的参数过多,采用手动拼接JSON ...
- angularjs中ckeditor的destroy问题
项目中,在切换了页面的tab页后会发现上传图片的操作报错,检查后发现问题根源是切换了tab页重新加载页面时ckeditor又会创建一次,这个时候的ckeditor已经不是第一次创建的那个了,所以上传图 ...
- nginx中的超时设置
nginx使用proxy模块时,默认的读取超时时间是60s. 1. send_timeout syntax: send_timeout the time default: send_timeout 6 ...
- 对于angularJS的一点思考
已经找好工作近两周了,入职基本上还算顺利,自己两年来的挑灯夜战也算是有了收获,于是这两周基本上是按部就班的工作,没有学习什么新技术.在上个公司的时候,同事在项目中使用angularJs,之前他也没有接 ...
- python3--函数(函数,全局变量和局部变量,递归函数)
1.1函数 1.1.1什么是函数 函数就是程序实现模块化的基本单元,一般实现某一功能的集合.函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能, ...
- Python学习笔记——条件和循环
1.条件表达式 >>> x = 3 >>> x = 1 if x<3 else 2 >>> x 2 2.for语句用于序列类型 <1& ...