【暑假】[实用数据结构]KMP

KMP算法

KMP算法是字符串匹配算法,可以在O(n)的时间完成,算法包含两部分,分别是:构造适配函数与两串匹配。

失配边的使用大大提高了算法效率,可以理解为已经成功匹配的字符不在重新匹配,因为我们已经知道它是什么,对应到算法中 匹配失败后应该在最大前缀之后继续匹配,因为某后缀已与最大前缀匹配成功而不用重新比较。

以下为代码实现:

 1 const int maxn = 1000 + 5;
 2
 3 void getFail(char* P,int* f){  //构造失配边
 4     int n=strlen(P);
 5     f[0]=f[1]=0;
 6     for(int i=0;i<n;i++){  //自己和自己匹配
 7         int j=f[i];
 8         while(j && P[i]!=P[j]) j=f[j];
 9         f[i+1]= P[i]==P[j]? j+1 : 0;
10     }
11 }
12
13 //可以如是理解f数组,f[i]表示到i与后缀成功匹配的最大前缀的下一指针
14 //f数组节约了算法时间,对于已知(已比较)的字符不在重新比较
15
16 void KMP(char* T,char* P){
17 int f[maxn];
18 int n=strlen(T), m=strlen(P);
19   getFail(P,f);
20   int j=0;
21   for(int i=0;i<n;i++){
22       while(j && T[i] != P[j]) j=f[j];  //沿失配边走
23       if(T[i]==P[j]) j++;
24       if(j==m) { printf("%d\n",i-m+1); j=0; }   //成功匹配P,输出匹配点
25       //将j重调为0代表重新检查,否则P[j]调用出错
26   }
27 }

有趣的是,在这里发现了作者的一个小错误,如果使字符串成功匹配所有位置且KMP算法可以完成的话,需要加入语句j=0;而在课本中这条语句是没有的。

时间: 2024-10-19 06:44:09

【暑假】[实用数据结构]KMP的相关文章

数据结构--KMP算法总结

数据结构—KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会,后边next数组会在介绍) 上图T为主链,P为模板链,要求P在T中是否出现,出现就返回位置. 朴素算法会顺序遍历,比较第一次的时候p[0]处失配,然后向后移动继续匹配.数据量大的时候这么做肯定是不可行的.所以这里就会有KMP算法!在一次失配之后,KMP算法认为这里已经失配了,就不能在比较一遍了,而是

数据结构--KMP模式匹配算法

今天,在看数据结构--串这一章节时,看到了KMP算法,相对较复杂些,在此单独做下整理. kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法).KMP算法的关键是根据给定的模式串W1,m,定义一个next函数.next函数包含了模式串本身局部匹配的信息. 例子: 假如我们要比较两个字符串是否相等. 在T串中查找S串.我们用最笨的方法去想,就是将T串与S串中的每一个元素一一去匹配,

数据结构- KMP

数据结构 - KMP 引言 & 介绍 由于李总说过串这一章只讲一个KMP, 所以我这里也就只说一个KMP算法了 KMP算法, 说得简单点就是关键字搜索 一般方法 一般的关键字搜索的算法为: 1 int Search(string a, string b) { 2 int lena = a.length(); 3 int lenb = b.length(); 4 int i = 0, j = 0; 5 6 while (i < lena && j < lenb) { 7

【暑假】[实用数据结构]UVAlive 3026 Period

UVAlive 3026 Period 题目: Period Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive),

【暑假】[实用数据结构]UVAlive

题目:   Dominating Patterns Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description The archaeologists are going to decipher a very mysterious ``language". Now, they know many language patterns; each patt

【暑假】[实用数据结构]UVAlive 3942 Remember the Word

UVAlive 3942 Remember the Word 题目: Remember the Word Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Neal is very curious about combinatorial problems, and now here comes a problem about words. Know

【暑假】[实用数据结构] AC自动机

Aho-Corasick自动机 AC自动机用于解决文本一个而模板有多个的问题. 作者所给模板如下: 1 struct AhoCorasickAutomata { 2 int ch[MAXNODE][SIGMA_SIZE]; 3 int f[MAXNODE]; // fail函数 4 int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val 5 int last[MAXNODE]; // 输出链表的下一个结点 6 int cnt[MAXS]; 7 int sz; 8 9

【暑假】[实用数据结构]前缀树 Trie

前缀树Trie Trie可理解为一个能够快速插入与查询的集合,无论是插入还是查询所需时间都为O(m) 模板如下: 1 const int maxnode = 1000+10; 2 const int sigma_size = 26; 3 4 struct Trie{ 5 int ch[maxnode][sigma_size]; 6 int val[maxnode]; 7 int sz; 8 9 void clear(){ sz=1; memset(ch[0],0,sizeof(ch[0]));

【暑假】[实用数据结构]动态范围查询问题

动态范围查询问题: 一.线段树+点修改   支持操作: Update(x,v): 将Ax修改为v Query(L,R) : 计算[L,R]内的最小值 1 int minv[maxn]; 2 int ql,qr; 3 int Query(int u,int L,int R){ 4 int M=L + (R-L)/2 , ans=INF; 5 if(ql<=L && R<=qr) return minv[u]; 6 if(ql <= M) ans=min(ans,Query(