字符串专题: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算法的思想是 ...
随机推荐
- PAT 1034. 有理数四则运算(20)
本题要求编写程序,计算2个有理数的和.差.积.商. 输入格式: 输入在一行中按照"a1/b1 a2/b2"的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只 ...
- 国内外前端(js)开发框架对比
国内外前端开发框架对比 首先我们先对目前国内外主流前端开发框架做一个基本的了解,之后再对他们进行一个直观的对比. Bootstrap Bootstrap(http://www.bootcss.com) ...
- DOCKER是什么,它解决了什么问题?(转)
Docker 虚拟机 1. docker与虚拟机性能比较 2. 如日中天的Docker解决了什么问题?
- async/await Task Timeout
async/await Task Timeout 在日常的电脑使用过程中,估计最难以忍受的就是软件界面"卡住""无响应",在我有限的开发生涯中一直都是在挑战 它 ...
- 通过sqlserver发送邮件
配置过程请参考:http://www.2cto.com/database/201403/289114.html 实际中应用的扩展: 1.编写一个触发器(相当于一个多线程的发邮件的服务). 2.在应用程 ...
- MarkdownPad2 Pro v2.4.2.29969 专业中文破解版完美支持table表格语法
在网上搞了半天,终于搞定了支持table简写语法的markdown软件. 下载地址:http://download.csdn.net/detail/wang_jun_hua/8180717 下载包内含 ...
- 84 tune2fs-调整系统参数
tune2fs命令允许系统管理员调整"ext2/ext3"文件系统中的可该参数.Windows下面如果出现意外断电死机情况,下次开机一般都会出现系统自检.Linux系统下面也有文件 ...
- iOS地图 -- 定位初使用
iOS的定位服务用到的框架是#import <CoreLocation/CoreLocation.h> 定位中用到的类是CLLocationManager 一.iOS8.0之前的定位 向用 ...
- ORACLE 中的 ROW_NUMBER() OVER() 分析函数的用法
ORACLE 中的 ROW_NUMBER() OVER() 分析函数的用法 ROW_NUMBER() OVER(partition by col1 order by col2) 表示根据col1分组, ...
- 【USACO 3.1】Contact(01子串按出现次数排序)
题意:给你一个01字符串,将长度为a到b之间(包含a.b)的子串按照出现次数排序.注意输入输出格式 题解:01子串对应一个二进制,为了区别11和011这样的不同子串,我们把长度也记录下来,官方题解是在 ...