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的更多相关文章

  1. LeetCode 字符串专题(一)

    目录 LeetCode 字符串专题 <c++> \([5]\) Longest Palindromic Substring \([28]\) Implement strStr() [\(4 ...

  2. NOIP2018提高组金牌训练营——字符串专题

    NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式.   a|bb|aabaa - 3 个 ...

  3. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  4. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

  5. 字符串专题:map POJ 1002

    第一次用到是在‘校内赛总结’扫地那道题里面,大同小异 map<string,int>str 可以专用做做字符串的匹配之类的处理 string donser; str [donser]++ ...

  6. 字符串KMP || POJ 2185 Milking Grid

    求一个最小矩阵,经过复制能够覆盖原矩阵(覆盖,不是填充,复制之后可以有多的) *解法:横着竖着kmp,求最大公倍数的做法是不对的,见http://blog.sina.com.cn/s/blog_69c ...

  7. 并不对劲的字符串专题(二):kmp

    据说这些并不对劲的内容是<信息学奥赛一本通提高篇>的配套练习. 先感叹一句<信息学奥赛一本通提高篇>上对kmp的解释和matrix67的博客相似度99%(还抄错了),莫非mat ...

  8. 字符串截取模板 && POJ 3450、3080 ( 暴力枚举子串 && KMP匹配 )

    //截取字符串 ch 的 st~en 这一段子串返回子串的首地址 //注意用完需要根据需要最后free()掉 char* substring(char* ch,int st,int en) { ; c ...

  9. 字符串专题之KMP算法

    写点自己对KMP的理解,我们有两个字符串A和B,求A中B出现了多少次. 这种问题就可以用KMP来求解. 朴素的匹配最坏情况是O(n^2)的.KMP是个高效的算法,效率是O(n)的. KMP算法的思想是 ...

随机推荐

  1. [No000080]右键解锁增强Chrome插件开发,破除防复制

    昨天用360极速(虽然我不喜欢360.)浏览器,登陆知乎查阅一些东西,突然感觉有些观点很赞同,想copy转载一下,我了个去,它丫的居然不让我复制. 地址:https://www.zhihu.com/q ...

  2. Laravel五大功能之Eloquent关系模式

    Eloquent是Laravel的原始ActiveRecord是实现的,建立在Laravel的Fluent Query Builder之上的,所以Eloquent类和Fluent类是一样的,能实现复杂 ...

  3. JS文件加载:比较async和DOM Script

    async与script动态加载都能使文件异步加载,本文叙述它们对页面渲染和load加载的影响方面. 目前我用demo.js作为执行文件操作.代码: var now = function() { re ...

  4. VS2012使用Git并连接到osc@git

    1.下载GitExtensions并安装 在http://sourceforge.net/projects/gitextensions/files/latest/download 下载 安装时请注意 ...

  5. AppBox升级进行时 - 关联表查询与更新(Entity Framework)

    AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. 关联表的查询操作 使用 Include 方法,我们可以在一次数据库查询中将关联 ...

  6. Css--深入学习之三角形气泡窗

    本文是作者从别的网站和文章学习了解的知识,简单做了个笔记,想要学习更多的可以参考这里:[css进阶]伪元素的妙用--单标签之美,奇思妙想 一.三角形的实现 首先,先画了三角形,后面二.三都是根据这个 ...

  7. 使用Fragment创建灵活的用户界面

      什么是Fragment         Fragment的作用像Activity一样,主要用于呈现用户界面,它依附于Activity存在,但比Activity更灵活. 当我们需要创建动态的,多面板 ...

  8. jquery版的全选,全不选和反选

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <script src ...

  9. BZOJ 1968: [Ahoi2005]COMMON 约数研究

    1968: [Ahoi2005]COMMON 约数研究 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 2032  Solved: 1537[Submit] ...

  10. Outlook2016 新装进阶操作指南

    启动图片自动下载 键盘上同时按下WIN+R,弹出运行输入框,输入outlook,回车后打开Outlook 依次点击左上角文件,选项,信任中心,信任中心设置,自动下载 在窗口右边反勾选"在HT ...