kmp算法巩固 以poj3461为试验
2013-08-28 22:41
253 查看
本来计划下一步去搞AC自动机的……忽发现它以KMP为基础……虽然假期练过,但基本内涵都不太清楚了,都是直接套模板Orz……是本次来再补一下(⊙﹏⊙) ,总算把自己的板给写出来了,真是可喜可贺XD
以下先是KMP的重新理解部分:用parent[]表示母串,son[]表示子串
当比较母串和子串时,以abcdefg和bcdf为例
母串: a b c d e f g
子串: b c d f
序号: 0 1 2 3 4
当比较到上面这一步时,可发现son[2]与parent[2]失配。如果是朴素算法,接下来会把子串右移,重新比较,而当比较到第x位时,子串的前x位与对应母串的的前x位相同,所以可以预处理子串的情况,先把子串与子串本身比较,当第x位失配时,子串要右移到第几位为止,这样就不需要每次都右移一位,一个个地试了。把需要右移到第几位的值保存在一个next数组中。我见过的next数组求法都不知道几组了QAQ,而且还难理解,果然要自己来写才行……
以下是今天写的一个模板:
然后找了道水题试了一下……稍微改下模板就能过了真是太赞!XD
题号是poj
自从trie后就喜欢上用struct了……看起来比较方便QvQ,但是总归得用class比较好吧……下次再想,明天可准备自动机了=w=
以下先是KMP的重新理解部分:用parent[]表示母串,son[]表示子串
当比较母串和子串时,以abcdefg和bcdf为例
母串: a b c d e f g
子串: b c d f
序号: 0 1 2 3 4
当比较到上面这一步时,可发现son[2]与parent[2]失配。如果是朴素算法,接下来会把子串右移,重新比较,而当比较到第x位时,子串的前x位与对应母串的的前x位相同,所以可以预处理子串的情况,先把子串与子串本身比较,当第x位失配时,子串要右移到第几位为止,这样就不需要每次都右移一位,一个个地试了。把需要右移到第几位的值保存在一个next数组中。我见过的next数组求法都不知道几组了QAQ,而且还难理解,果然要自己来写才行……
以下是今天写的一个模板:
//该模板用来找子串在母串中是否存在,若存在,返回起始点,否则,返回-1 const int maxsize=100010; struct KMP { char parent[maxsize];int parentlen; char son[maxsize];int sonlen; int next[maxsize]; void init() { memset(next, 0, sizeof(next)); return ; } void insert() { scanf("%s", parent); parentlen=strlen(parent); scanf("%s", son); sonlen=strlen(son); return ; } void buildnext() { int pos=2, cnt=0; next[0]=-1;next[1]=0; while(pos<=sonlen) { if(son[pos-1]==son[cnt]) next[pos++]=++cnt; else if(cnt>0) cnt=next[cnt]; else pos++; } return ; } int compare() { int parentcnt=0, soncnt=0; while(parentcnt<=parentlen) { if(parent[parentcnt]==son[soncnt]) { parentcnt++;soncnt++; } else if(soncnt>0) soncnt=next[soncnt]; else parentcnt++; if(soncnt==sonlen) return parentcnt-soncnt+1; } return -1; } }kmp;
然后找了道水题试了一下……稍微改下模板就能过了真是太赞!XD
题号是poj
#include<cstdio> #include<cstring> const int maxsize=1000010; struct KMP { char parent[maxsize];int parentlen; char son[maxsize];int sonlen; int next[maxsize]; void init() { memset(next, 0, sizeof(next)); return ; } void insert() { scanf("%s", son); sonlen=strlen(son); scanf("%s", parent); parentlen=strlen(parent); return ; } void buildnext() { int pos=2, cnt=0; next[0]=-1;next[1]=0;next[sonlen]=0; while(pos<=sonlen) { if(son[pos-1]==son[cnt]) next[pos++]=++cnt; else if(cnt>0) cnt=next[cnt]; else pos++; } return ; } int compare() { int parentcnt=0, soncnt=0; int ret=0; while(parentcnt<=parentlen) { if(parent[parentcnt]==son[soncnt]) { parentcnt++;soncnt++; } else if(soncnt>0) soncnt=next[soncnt]; else parentcnt++; if(soncnt==sonlen) ret++; } return ret; } }kmp; int main() { int ncase; int ans; scanf("%d", &ncase); while(ncase--) { kmp.init(); kmp.insert(); kmp.buildnext(); ans=kmp.compare(); printf("%d\n", ans); } return 0; }
自从trie后就喜欢上用struct了……看起来比较方便QvQ,但是总归得用class比较好吧……下次再想,明天可准备自动机了=w=
相关文章推荐
- poj 2406 kmp算法巩固之next数组的再理解
- 再谈kmp算法 , 由poj3461
- kmp算法 in POJ【POJ3461,POJ2752,POJ2406,POJ1961】
- POJ3461 KMP算法
- KMP算法--poj3461
- POJ3461 Oulipo ——KMP算法——Pku3461
- 【POJ3461】KMP算法理解 for 初学者
- POJ3461 Oulipo KMP算法
- POJ3461 Oulipo KMP算法应用
- KMP算法模板及问题解决(HDU 1711)(hihocoder 1015 KMP)(HDU 1686)(POJ3461)(HDU1358)
- poj3461KMP算法模板
- POJ3461 HDU1686(KMP算法)
- C语言数据结构KMP算法实现模式串主串匹配(数据结构第三次试验)
- KMP算法的next、next value数组代码实现及POJ3461
- poj3461 KMP算法(字符串匹配)
- 关于 TCP 并发连接的几个思考题与试验
- KMP算法
- KMP算法(2)
- 【caffe跑试验遇到错误:Check failed: error == cudaSuccess (2 vs. 0) out of memory】:
- 数据结构之KMP算法---hdu2087---剪花布条