改进KMP模式匹配算法

看了算法的大致步骤,然后自己一一证明了每一步的正确性,注释里写了一些理解。

这也不是新鲜的做法,只是感觉这个程序非常精巧,反复地使用数学归纳法。

让我感觉很新鲜。

 1 /*
 2     next[i]存放:match[i]处失配,orig在对应位置将要匹配的值
 3                  按照KMP的思想,
 4                  即是1到i-1子串中最长相同前后缀的前缀最后一项的后一项
 5                  且这一项和match[i]不同
 6
 7                  若不存在同缀子串但是第一项与i项不同,值为1。
 8                  若不存在同缀子串且第一项与i项相同,值为0,即将j向后移动一个位置。
 9 */
10 #include<stdio.h>
11 int main(void)
12  {
13      char orig[100],match[100];
14     int nexterval[100],next[100],lengthOrig,lengthMatch;
15     for(lengthOrig=1;;lengthOrig++){
16         char ch;
17         scanf("%c",&ch);
18         if(ch==‘\n‘||ch==‘ ‘){
19             lengthOrig--;
20             break;
21         }
22         orig[lengthOrig]=ch;
23     }
24     for(lengthMatch=1;;lengthMatch++){
25         char ch;
26         scanf("%c",&ch);
27         if(ch==‘\n‘||ch==‘ ‘){
28             lengthMatch--;
29             break;
30         }
31         match[lengthMatch]=ch;
32     }
33     next[1]=0;
34     next[2]=1;
35     for(int i=3;i<=lengthMatch+1;i++){//next中存储若i位不匹配则将要匹配的对象
36         int k=i-1;                  //即为 1到i-1中最长前缀最后一项的后一个数
37         while(1){
38             if(k==1){
39                 next[i]=1;
40                 break;
41             }
42             if(match[i-1]==match[next[k]]){
43                 next[i]=next[k]+1;
44                 break;
45             }
46             k=next[k];//若不能延长形成子串next[k]+1
47         }              //而且还存在子串m,那这个子串一定是前一子串的子串
48     }
49     for(int i=2;i<=lengthMatch+1;i++){//若i!=0,match[next[i]]与match[i]一定不同
50         if(match[i]==match[next[i]])//  若match[i]==match[next[i]]
51             next[i]=next[next[i]];//    已经有match[next[i]]!=match[next[next[i]]]
52     }//                                    一定有match[i]!=match[next[next[i]]]
53     int i=1,j=1,total=0;
54     while(1){//while结束时i前面的项已经和j前面的匹配,且之前的所有匹配已经尝试过了
55         if(i==lengthMatch+1){
56             ++total;
57             i=next[i];
58             continue;
59         }//i-1到头即成功匹配一次
60         if(j==lengthOrig+1)        break;
61         //当j-1已经到头 i-1尚未到头时由于orig的长度限制已经不能匹配了
62         if(i==0){
63             ++j,++i;
64             continue;
65         }//第一项配不上 同时向后考虑一位
66         if(match[i]==orig[j])    ++i,++j;
67         else                    i=next[i];
68     }
69     printf("They are match for %d times.",total);
70  } 

原文地址:https://www.cnblogs.com/luozhonghao/p/9032723.html

时间: 2024-10-15 04:56:53

改进KMP模式匹配算法的相关文章

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

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

详细解读KMP模式匹配算法

转载请注明出处:http://blog.csdn.net/fightlei/article/details/52712461 首先我们需要了解什么是模式匹配? 子串定位运算又称为模式匹配(Pattern Matching)或串匹配(String Matching).在串匹配中,一般将主串称为目标串,将子串称为模式串.本篇博客统一用S表示目标串,T表示模式串,将从目标串S中查找模式串T的过程称为模式匹配. 虽然我们的主角是KMP模式匹配算法,但我们还是要先从暴力匹配算法讲起,通过发现暴力匹配算法存

朴素和KMP模式匹配算法(Java)

朴素模式匹配算法 public class Test { //朴素模式匹配算法 public int Index(String s,String t,int pos){ int i = pos;//主串中第几个位置开始比较 int j = 0;//模式串中的第一个位置 while(i<s.length()&&j<t.length()){ if(s.charAt(i)==t.charAt(j)){ i++; j++; }else { i = i-j+1;//主串的下一个位置 j

Java数据结构-串及其应用-KMP模式匹配算法

串(string)是由零个或多个宇符组成的有限序列,又名叫字符串. 定义的解释: ??串中的字符数目n称为串的长度,定义中谈到"有限"是指长度n是一个有限的数值. ??零个字符的串称为空串(null string),它的长度为零,可以直接用两双引号一表示,也可以用希腊Φ字母来表示. ??所谓的序列,说明串的相邻字符之间具有前驱和后继的关系. 下面是串的一些概念性东西: ??空格串,是只包含空格的串.注意它与空串的区别,空格串是有内容有长度的,而且可以不止一个空格. ??子串与主串,串中

改进版KMP模式匹配算法

背景 朴素匹配算法太低效了.冗余过多,已经比较过的,没必要重复:可以从比较结果中推导出来的,也没必要再重复. 核心 主串不回溯,变化要匹配的串的下一次比较的位置. 实现 两个函数,一个提供next数组,即存储要匹配的串的每一个元素匹配失败后,下一次要比较的位置的数组.另一个实现匹配. java代码 public class KMP {//获取next数组private int[] getNext(char[] t_char){int size = t_char.length;int next[]

串-KMP模式匹配算法(nextval数组)

#include <stdio.h> #include <stdlib.h> #include <string.h> void get_next(char T[100],int *next); int Index_KMP(char S[100],char T[100],int pos); int main() { int n; char S[100],T[100]; gets(S); gets(T); n=Index_KMP(S,T,2); printf("%

数据结构(三)串---KMP模式匹配算法实现及优化

KMP算法实现 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 40 typedef int ElemType; typedef int Status; //设置串的存储结构 typede

【数据结构和算法】:KMP模式匹配算法

Knuth-Morris-Pratt 字符串查找算法,简称为 "KMP算法",常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth.Vaughan Pratt.James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法.整个KMP的重点就在于当某一个字符与主串不匹配时,我们应该知道j指针要移动到哪里. 如图:C和D不匹配了,我们要把j移动到哪?显然是第1位,因为如下面蓝框所示,前面A已经匹配. 下面也如此: 可以把j指针移动到第

数据结构(三)串---KMP模式匹配算法之获取next数组

(一)获取模式串T的next数组值 1.回顾 我们所知道的KMP算法next数组的作用 next[j]表示当前模式串T的j下标对目标串S的i值失配时,我们应该使用模式串的下标为next[j]接着去和目标串失配的i值进行匹配 而KMP算法的next求值函数 我们可以知道next除了j=1时,next[1]为0,其他情况都是比较前缀和后缀串的相似度(第三种情况是当相似度为0时,next值为0+1=1) next数组,是用来评判前后缀的相识度,而next值,则是等于相似度加一 2.思考 虽然我们知道是