模式匹配KMP算法实验报告

合集下载

模式匹配KMP算法研究报告

模式匹配KMP算法研究报告

模式匹配的KMP算法研究学生姓名:黄飞指导老师:罗心摘要在计算机科学领域,串的模式匹配<以下简称为串匹配)算法一直都是研究焦点之一。

在拼写检查、语言翻译、数据压缩、搜索引擎、网络入侵检测、计算机病毒特征码匹配以及DNA序列匹配等应用中,都需要进行串匹配。

串匹配就是在主串中查找模式串的一个或所有出现。

在本文中主串表示为S=s1s2s3…sn,模式串表示为T=t1t2…tm。

串匹配从方式上可分为精确匹配、模糊匹配、并行匹配等,著名的匹配算法有BF算法、KMP算法、BM算法及一些改进算法。

本文主要在精确匹配方面对KMP算法进行了讨论并对它做一些改进以及利用改进的KMP来实现多次模式匹配。

关键字:模式匹配;主串;模式串;KMP算法Research and Analysis of KMP Pattern MatchingAlgorithmStudent:Huangfei Teacher:LuoxinAbstract In computer science,String pattern matching(Hereinafter referred to as the string matching>algorithmis always the focus of the study.In thespell check, language translation, data compression, search engine, thenetwork intrusion detection system, a computer virus signature matching DNAsequences and the application in the match,matched to string matching.String matching is in search of a string of pattern or all appear.In this paper, the string is S = s1s2s3... Sn, string pattern for T = t1t2... tm.String matching way can be divided from the accurate matching, fuzzy matching, parallel matching etc., the famous matching algorithms are KMP algorithm, BF algorithm, the algorithm and some BM algorithm.This paper in precise KMP algorithm for matching aspects are discussed and some improvement on it and using the improved KMP to realize the multiple pattern matching.Key words: pattern matching, The string。

串的模式匹配算法实验报告

串的模式匹配算法实验报告

竭诚为您提供优质文档/双击可除串的模式匹配算法实验报告篇一:串的模式匹配算法串的匹配算法——bruteForce(bF)算法匹配模式的定义设有主串s和子串T,子串T的定位就是要在主串s中找到一个与子串T相等的子串。

通常把主串s称为目标串,把子串T称为模式串,因此定位也称作模式匹配。

模式匹配成功是指在目标串s中找到一个模式串T;不成功则指目标串s中不存在模式串T。

bF算法brute-Force算法简称为bF算法,其基本思路是:从目标串s的第一个字符开始和模式串T中的第一个字符比较,若相等,则继续逐个比较后续的字符;否则从目标串s的第二个字符开始重新与模式串T的第一个字符进行比较。

以此类推,若从模式串T的第i个字符开始,每个字符依次和目标串s中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,算法返回0。

实现代码如下:/*返回子串T在主串s中第pos个字符之后的位置。

若不存在,则函数返回值为0./*T非空。

intindex(strings,stringT,intpos){inti=pos;//用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配intj=1;//j用于子串T中当前位置下标值while(i j=1;}if(j>T[0])returni-T[0];elsereturn0;}}bF算法的时间复杂度若n为主串长度,m为子串长度则最好的情况是:一配就中,只比较了m次。

最坏的情况是:主串前面n-m个位置都部分匹配到子串的最后一位,即这n-m位比较了m次,最后m位也各比较了一次,还要加上m,所以总次数为:(n-m)*m+m=(n-m+1)*m从最好到最坏情况统计总的比较次数,然后取平均,得到一般情况是o(n+m).篇二:数据结构实验报告-串实验四串【实验目的】1、掌握串的存储表示及基本操作;2、掌握串的两种模式匹配算法:bF和Kmp。

3、了解串的应用。

【实验学时】2学时【实验预习】回答以下问题:1、串和子串的定义串的定义:串是由零个或多个任意字符组成的有限序列。

实验六 串的模式匹配

实验六 串的模式匹配

⑵用KMP算法进行匹配。 (3)程序运行的结果要在屏幕上显示:

简单的朴素模式匹配算法中,模式串的位置、出现的次数。 模式串的next函数值。 说明:下课前请将源代码的.c(或.cpp) KMP算法的匹配位置。 文件以及.h文件打包后重命名为
“p6_姓名简拼_学号后三位”, 然后提交到教师机!
【实验内容】编写程序,实现顺序串的模式匹配算法。 【基本要求】在主程序中调用算法,输入一个主串和模式串, 在主串中检索模式串,显示模式串在主串中出现的次数和 位置。 ⑴用简单的朴素模式匹配算法计模式串出现 的次数; 从主串的任意给定位置检索模式串。

【实现提示】
要统计模式串在主串中出现的次数,可以先确定从
主串中第一个字符起,模式串的位置,然后再利用 指定位置的匹配算法找出其他匹配的位置; 利用一个数组来存放所有模式串出现的位置,然后 将这些位置依次打印输出。 串值在数组中存储时,是从数组的0号单元开始存 放的。注意修改教材中Next函数和KMP算法函数 中的变量! 至少包含以下头文件: #include <stdio.h> #include <string.h> #include <conio.h>

串匹配算法实验报告

串匹配算法实验报告

一、实验目的1. 理解串匹配算法的基本原理和实现方法。

2. 掌握KMP算法和朴素算法的原理和实现过程。

3. 通过实验对比分析两种算法的性能,验证算法的效率和适用场景。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.73. 开发工具:PyCharm三、实验内容1. 串匹配算法的原理介绍2. 朴素算法的实现与测试3. KMP算法的实现与测试4. 两种算法的性能对比四、实验步骤1. 串匹配算法的原理介绍串匹配算法是指在一个文本串中查找一个模式串的位置。

常用的串匹配算法有朴素算法和KMP算法。

(1)朴素算法(Brute-Force算法):通过逐个字符比较主串和待匹配串,如果匹配成功,则返回匹配位置;如果匹配失败,则回溯到主串上的一个新位置,并在待匹配串上从头开始比较。

(2)KMP算法:通过构建一个部分匹配表(next数组),记录模式串中每个位置对应的最长相同前缀后缀的长度。

在匹配过程中,当出现不匹配时,通过查阅next数组确定子串指针回退位置,从而避免重复比较。

2. 朴素算法的实现与测试(1)实现朴素算法```pythondef brute_force_search(text, pattern):n = len(text)m = len(pattern)for i in range(n - m + 1):j = 0while j < m:if text[i + j] != pattern[j]:breakj += 1if j == m:return ireturn -1```(2)测试朴素算法```pythontext = "ABABDABACDABABCABAB"pattern = "ABABCABAB"print(brute_force_search(text, pattern)) # 输出:10 ```3. KMP算法的实现与测试(1)实现KMP算法```pythondef kmp_search(text, pattern):def build_next(pattern):next_array = [0] len(pattern)k = 0for i in range(1, len(pattern)):while k > 0 and pattern[k] != pattern[i]: k = next_array[k - 1]if pattern[k] == pattern[i]:k += 1next_array[i] = kreturn next_arrayn = len(text)m = len(pattern)next_array = build_next(pattern)k = 0for i in range(n):while k > 0 and text[i] != pattern[k]:k = next_array[k - 1]if text[i] == pattern[k]:k += 1if k == m:return i - m + 1return -1```(2)测试KMP算法```pythontext = "ABABDABACDABABCABAB"pattern = "ABABCABAB"print(kmp_search(text, pattern)) # 输出:10```4. 两种算法的性能对比为了对比两种算法的性能,我们分别测试了不同的文本串和模式串长度,并记录了运行时间。

数据结构实验报告 模式匹配算法

数据结构实验报告 模式匹配算法

return 1; } datatype DeQueue(SeqQueue *q) { datatype x; if(q->front==q->rear) { printf("\nempty!");return 0;} x=q->data[q->front]; q->front=(q->front+1)%max; return x; } void display(SeqQueue *q) { int s; s=q->front; if(q->front==q->rear) printf("empty!"); else while(s!=q->rear) { printf("->%d",q->data[s]); s=(s+1)%max; } printf("\n"); } main() { int a[6]={3,7,4,12,31,15},i; SeqQueue *p; p=InitQueue(); for(i=0;i<6;i++) EnQueue(p,a[i]); printf("output the queue values:"); display(p); printf("\n"); EnQueue(p,100);EnQueue(p,200);
ห้องสมุดไป่ตู้
元素并显示结果为4 ,12, 31, 15 ,100 ,200。
七、具体程序 #include "stdio.h" #include "conio.h" #define max 100 typedef int datatype; typedef struct { datatype data[max]; int front; int rear; }SeqQueue; SeqQueue *InitQueue() { SeqQueue *q; q=(SeqQueue *)malloc(sizeof(SeqQueue)); q->front=q->rear=0; return q; } int QueueEmpty(SeqQueue *q) { if (q->front==q->rear) return 1; else return 0; } int EnQueue(SeqQueue *q,datatype x) { if((q->rear+1)%max==q->front) {printf("\nfull!");return 0;} q->data[q->rear]=x; q->rear=(q->rear+1)%max;

串的数据结构实验报告

串的数据结构实验报告

串的数据结构实验报告串的数据结构实验报告一、引言在计算机科学中,串(String)是一种基本的数据结构,用于存储和操作字符序列。

串的数据结构在实际应用中具有广泛的用途,例如文本处理、搜索引擎、数据库等。

本实验旨在通过实践掌握串的基本操作和应用。

二、实验目的1. 理解串的概念和基本操作;2. 掌握串的存储结构和实现方式;3. 熟悉串的常见应用场景。

三、实验内容1. 串的定义和基本操作在本实验中,我们采用顺序存储结构来表示串。

顺序存储结构通过一个字符数组来存储串的字符序列,并使用一个整型变量来记录串的长度。

基本操作包括:- 初始化串- 求串的长度- 求子串- 串的连接- 串的比较2. 串的模式匹配串的模式匹配是串的一个重要应用场景。

在实验中,我们将实现朴素的模式匹配算法和KMP算法,并比较它们的性能差异。

四、实验步骤1. 串的定义和基本操作首先,我们定义一个结构体来表示串,并实现初始化串、求串的长度、求子串、串的连接和串的比较等基本操作。

2. 串的模式匹配a. 实现朴素的模式匹配算法朴素的模式匹配算法是一种简单但效率较低的算法。

它通过逐个比较主串和模式串的字符来确定是否匹配。

b. 实现KMP算法KMP算法是一种高效的模式匹配算法。

它通过利用已匹配字符的信息,避免不必要的比较,从而提高匹配效率。

3. 性能比较与分析对比朴素的模式匹配算法和KMP算法的性能差异,分析其时间复杂度和空间复杂度,并讨论适用场景。

五、实验结果与讨论1. 串的基本操作经过测试,我们成功实现了初始化串、求串的长度、求子串、串的连接和串的比较等基本操作,并验证了它们的正确性和效率。

2. 串的模式匹配我们对两种模式匹配算法进行了性能测试,并记录了它们的运行时间和内存占用情况。

结果表明,KMP算法相较于朴素算法,在大规模文本匹配任务中具有明显的优势。

六、实验总结通过本实验,我们深入学习了串的数据结构和基本操作,并掌握了串的模式匹配算法。

KMP模式匹配算法

KMP模式匹配算法

KMP模式匹配算法KMP算法是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。

该算法的核心思想是通过预处理模式串,构建一个部分匹配表,从而在匹配过程中尽量减少不必要的比较。

KMP算法的实现步骤如下:1.构建部分匹配表部分匹配表是一个数组,记录了模式串中每个位置的最长相等前后缀长度。

从模式串的第二个字符开始,依次计算每个位置的最长相等前后缀长度。

具体算法如下:-初始化部分匹配表的第一个位置为0,第二个位置为1- 从第三个位置开始,假设当前位置为i,则先找到i - 1位置的最长相等前后缀长度记为len,然后比较模式串中i位置的字符和模式串中len位置的字符是否相等。

- 如果相等,则i位置的最长相等前后缀长度为len + 1- 如果不相等,则继续判断len的最长相等前后缀长度,直到len为0或者找到相等的字符为止。

2.开始匹配在主串中从前往后依次查找模式串的出现位置。

设置两个指针i和j,分别指向主串和模式串的当前位置。

具体算法如下:-当主串和模式串的当前字符相等时,继续比较下一个字符,即i和j分别向后移动一个位置。

-当主串和模式串的当前字符不相等时,根据部分匹配表确定模式串指针j的下一个位置,即找到模式串中与主串当前字符相等的位置。

如果找到了相等的位置,则将j移动到相等位置的下一个位置,即j=部分匹配表[j];如果没有找到相等的位置,则将i移动到下一个位置,即i=i+13.检查匹配结果如果模式串指针j移动到了模式串的末尾,则说明匹配成功,返回主串中模式串的起始位置;如果主串指针i移动到了主串的末尾,则说明匹配失败,没有找到模式串。

KMP算法的时间复杂度为O(m+n),其中m为主串的长度,n为模式串的长度。

通过预处理模式串,KMP算法避免了在匹配过程中重复比较已经匹配过的字符,提高了匹配的效率。

总结:KMP算法通过构建部分匹配表,实现了在字符串匹配过程中快速定位模式串的位置,减少了不必要的比较操作。

计算机算法实验报告BF和KMP

计算机算法实验报告BF和KMP

天津市大学软件学院实验报告课程名称:串匹配算法实验姓名:***学号:**********班级:业务1114串匹配问题一、实验题目:给定一个主串,在该主串中查找并定位任意给定字符串。

二、实验目的:(1)深刻理解并掌握蛮力法的设计思想;(2)提高应用蛮力法设计算法的技能;(3)理解这样一个观点:用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对算法的第一个版本进行一定程度的改良,改进其时间性能。

三、实验分析:串匹配问题的BF算法1 在串S中和串T中设比较的下标i=1和j=1;2 循环直到S中所剩字符个数小于T的长度或T中所有字符均比较完2.1 k=i2.2 如果S[i]=T[j],则比较S和T的下一字符,否则2.2 将i和j回溯(i=k+1; j=1)3 如果T中所有字符均比较完,则匹配成功,返回k否则匹配失败,返回0时间复杂度:设匹配成功发生在si处,则在i-1趟不成功的匹配中比较了(i-1)m次,第i趟成功匹配共比较了m次,所以总共比较了i m次,因此平均比较次数是:pi(i m)=(i m)=一般情况下,m<<n,因此最坏情况下时间复杂度是Ο(n m)。

串匹配问题的KMP算法实现过程:在串S和串T中高比较的起始下标i和j;循环直到S中所剩字符小于T的长度或T的所有字符均比较完(如果S[i]=T[j],则继续比较S和T的下一个字符;否则将j向右滑动到next[j]位置,即j=next[j];如果j=0,则将i和j分别+1,准备下趟比较,至于其中的next在此不作详细讲解);如果T中所有字符均比较完,则匹配成功,返回匹配的起始下标;否则匹配失败,返回0。

时间复杂度:Ο(n m),当m<<n时,KMP算法的时间复杂性是Ο(n)。

四、实验所用语言和运行环境C++,运行环境Microsoft Visual C++ 6.0五、实验过程的原始记录BF算法程序代码#include<iostream.h>#include<string>void main(){cout<<"请输入主串并且以0和回车结束"<<endl;char s[100];char t[100];for(int m=0;m<100;m++){cin>>s[m];if(s[m]=='0'){s[m]='\0';break;}}cout<<"您输入的主串为:";for(int o=0;o<strlen(s);++o){cout<<s[o];}cout<<endl;cout<<"主串长度:";cout<<strlen(s);cout<<endl<<endl;cout<<"请输入子串并且以0和回车结束"<<endl;for(int n=0;n<100;n++){cin>>t[n];if(t[n]=='0'){t[n]='\0';break;}}cout<<"您输入的子串为:";for(int a=0;a<strlen(t);++a){cout<<t[a];}cout<<endl;cout<<"子串长度:";cout<<strlen(t);cout<<endl;cout<<endl<<"++++++++BF算法++++++++"<<endl;int i,j,k,y=0;for(i=0;i<strlen(s)-strlen(t)+1;){k=i;for(j=0;j<strlen(t);)if(s[i]==t[j]){if(j==strlen(t)-1){cout<<"找到了相同的字串:";cout<<"位置在主串的第"<<i-j+1<<"的位置上";cout<<endl;y=1;break;}++i;++j;}else{j=0;break;}}i=k+1;if(y==1)break;}if(i==strlen(s)-strlen(t)+1&&j!=strlen(t)-1){cout<<"没有找到可以匹配的子串"<<endl;}}程序执行结果:查找到了子串没有查找到子串程序代码#include<iostream.h>#include<string>//前缀函数值,用于KMP算法int GETNEXT(char t[],int b){int NEXT[10];NEXT[0]=-1;int j,k;j=0;k=-1;while(j<strlen(t)){if ((k==-1)||(t[j]==t[k])){j++;k++;NEXT[j]=k;}else k=NEXT[k];}b=NEXT[b];return b;}int KMP(char s[],char t[]){int a=0;int b=0;int m,n;m=strlen(s); //主串长度n=strlen(t); //子串长度cout<<endl<<"+++++++++KMP算法++++++++++++"<<endl;while(a<=m-n){while(s[a]==t[b]&&b!=n){a++;b++;}if(b==n){cout<<"找到了相应的子串位置在主串:"<<a-b+1<<endl;return 0;}b=GETNEXT(t,b);a=a-b;if(b==-1) b++;}cout<<"没有找到匹配的子串!"<<endl;return 0;}void main(){cout<<"请输入主串并且以0和回车结束"<<endl;char s[100];char t[100];for(int m=0;m<100;m++){cin>>s[m];if(s[m]=='0'){s[m]='\0';break;}}cout<<"您输入的主串为:";for(int o=0;o<strlen(s);++o){cout<<s[o];}cout<<endl;cout<<"主串长度:";cout<<strlen(s);cout<<endl<<endl;cout<<"请输入子串并且以0和回车结束"<<endl;for(int n=0;n<100;n++){cin>>t[n];if(t[n]=='0'){t[n]='\0';break;}}cout<<"您输入的子串为:";for(int a=0;a<strlen(t);++a){cout<<t[a];}cout<<endl;cout<<"子串长度:";cout<<strlen(t);cout<<endl;KMP(s,t);}程序执行结果:查找到子串没有查到子串。

串的实验报告总结

串的实验报告总结

串的实验报告总结本次实验旨在研究串(String)数据类型在计算机编程中的应用。

通过对串的基本操作和常见算法进行实验,探索串在字符串处理、文本编辑等方面的实际应用。

本报告将总结实验过程、结果及结论,并提出对进一步研究的展望。

实验内容与方法1.实验内容本次实验主要包括以下内容:-字符串的输入和输出;-串的基本操作,如串的连接、截取、插入等;-串的模式匹配算法,如KMP算法;-串的排序算法,如快速排序。

2.实验方法为了完成上述实验内容,我们采用了以下方法:-使用编程语言(如C++、Java)来实现串数据类型及其相关操作;-设计测试样例,验证实现的正确性和效率;-运行程序,记录实验结果并进行分析。

实验结果与分析经过实验,我们得到了以下结果和分析:1.字符串的输入和输出操作实现了预期的功能,可以正确地读取和显示字符串数据。

2.串的基本操作(连接、截取、插入等)能够正确地处理字符串,并且具有良好的效率。

3.KMP算法作为一种高效的模式匹配算法,能够快速地在文本中搜索指定的模式串,并返回匹配结果。

4.快速排序算法作为一种常用的排序算法,在处理大量字符串数据时表现出了较高的效率。

结论与展望通过本次实验,我们对串数据类型及其基本操作和常见算法有了更深入的理解。

串在计算机编程中具有重要的应用价值,特别是在字符串处理和文本编辑方面。

实验结果显示,实现的串操作功能正常,并且在性能上达到了预期的要求。

然而,本次实验还有改进和拓展的空间。

首先,可以进一步研究优化串的操作效率,提升算法的执行速度。

其次,可以探索更多的串算法,如字符串匹配的其他算法(如BM算法、Trie树等)以及字符串压缩算法等。

此外,可以考虑将串的应用扩展到更多领域,如自然语言处理、数据挖掘等。

综上所述,本次实验对于串数据类型的研究和应用具有重要意义,为进一步深入探索串的应用提供了基础和启示。

我们期待未来在串的研究中取得更多的成果,并将其应用于实际的计算机编程和软件开发中。

数据结构串的实验报告

数据结构串的实验报告

一、实验目的1. 理解串的定义、性质和操作;2. 掌握串的基本操作,如串的创建、复制、连接、求子串、求逆序、求长度等;3. 熟练运用串的常用算法,如串的模式匹配算法(如KMP算法);4. 培养编程能力和算法设计能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 串的创建与初始化2. 串的复制3. 串的连接4. 串的求子串5. 串的求逆序6. 串的求长度7. 串的模式匹配算法(KMP算法)四、实验步骤1. 串的创建与初始化(1)创建一个串对象;(2)初始化串的长度;(3)初始化串的内容。

2. 串的复制(1)创建一个目标串对象;(2)使用复制构造函数将源串复制到目标串。

3. 串的连接(1)创建一个目标串对象;(2)使用连接函数将源串连接到目标串。

4. 串的求子串(1)创建一个目标串对象;(2)使用求子串函数从源串中提取子串。

5. 串的求逆序(1)创建一个目标串对象;(2)使用逆序函数将源串逆序。

6. 串的求长度(1)获取源串的长度。

7. 串的模式匹配算法(KMP算法)(1)创建一个模式串对象;(2)使用KMP算法在源串中查找模式串。

五、实验结果与分析1. 串的创建与初始化实验结果:成功创建了一个串对象,并初始化了其长度和内容。

2. 串的复制实验结果:成功将源串复制到目标串。

3. 串的连接实验结果:成功将源串连接到目标串。

4. 串的求子串实验结果:成功从源串中提取了子串。

5. 串的求逆序实验结果:成功将源串逆序。

6. 串的求长度实验结果:成功获取了源串的长度。

7. 串的模式匹配算法(KMP算法)实验结果:成功在源串中找到了模式串。

六、实验总结通过本次实验,我对串的定义、性质和操作有了更深入的了解,掌握了串的基本操作和常用算法。

在实验过程中,我遇到了一些问题,如KMP算法的编写和调试,但在老师和同学的指导下,我成功地解决了这些问题。

字符串匹配kmp算法

字符串匹配kmp算法

字符串匹配kmp算法字符串匹配是计算机科学中的一个基本问题,它涉及在一个文本串中寻找一个模式串的出现位置。

其中,KMP算法是一种更加高效的算法,它不需要回溯匹配过的字符,在匹配失败的时候,根据已经匹配的字符和模式串前缀的匹配关系直接跳跃到下一次匹配的起点。

下面,我将详细介绍KMP算法原理及其实现。

1. KMP算法原理KMP算法的核心思想是:当模式串中的某个字符与文本串中的某个字符不相同时,根据已经匹配的字符和模式串前缀的匹配关系,跳过已经比较过的字符,从未匹配的字符开始重新匹配。

这个过程可以通过计算模式串的前缀函数(即next数组)来实现。

具体地,假设现在文本串为T,模式串为P,它们的长度分别为n和m。

当对于文本串T的第i个字符和模式串P的第j个字符(i和j都是从0开始计数的)进行匹配时:如果T[i]和P[j]相同,则i和j都加1,继续比较下一个字符;如果T[i]和P[j]不同,则j回溯到next[j](next[j]是P[0]到P[j-1]的一个子串中的最长的既是自身的前缀又是后缀的子串的长度),而i不会回溯,继续和P[next[j]]比较。

如果匹配成功,则返回i-j作为P在T中的起始位置;如果匹配失败,则继续执行上述过程,直到文本串T被遍历完或匹配成功为止。

2. KMP算法步骤(1)计算模式串的前缀函数next[j]。

next[j]表示P[0]到P[j-1]的一个子串中的最长的既是自身的前缀又是后缀的子串的长度。

具体计算方式如下:先令next[0]=-1,k=-1(其中k表示相等前缀的长度,初始化为-1),j=0。

从j=1向后遍历整个模式串P:如果k=-1或者P[j]=P[k],则next[j+1]=k+1,k=j,j+1;否则,令k=next[k],再次执行步骤2。

(2)使用next数组进行匹配。

从文本串T的第0个字符开始,从模式串P的第0个字符开始匹配,如果匹配失败,根据next数组进行回溯。

字符匹配查找实验报告(3篇)

字符匹配查找实验报告(3篇)

第1篇一、实验目的1. 理解字符匹配查找算法的基本原理。

2. 掌握几种常见的字符匹配查找方法,如暴力法、KMP算法、Boyer-Moore算法等。

3. 分析比较不同查找算法的效率,提高编程能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验原理字符匹配查找是指在一个文本中查找一个特定的子串,并返回子串在文本中的起始位置。

本实验主要研究了以下几种查找算法:1. 暴力法:逐个比较文本中的每个字符与子串的第一个字符,若匹配则继续比较下一个字符,否则回退一位重新比较。

2. KMP算法:通过预处理子串,构建一个部分匹配表,当主串与子串不匹配时,利用部分匹配表确定子串的下一个位置。

3. Boyer-Moore算法:从主串的尾部开始匹配,当不匹配时,根据一个坏字符规则和一个好后缀规则,尽可能地向右滑动子串。

四、实验内容1. 暴力法实现2. KMP算法实现3. Boyer-Moore算法实现4. 性能比较五、实验步骤1. 实现暴力法查找算法2. 实现KMP算法查找算法3. 实现Boyer-Moore算法查找算法4. 编写性能比较代码,对比三种算法的查找效率六、实验结果与分析1. 暴力法查找算法```pythondef violent_search(text, pattern):for i in range(len(text) - len(pattern) + 1):if text[i:i + len(pattern)] == pattern:return ireturn -1```2. KMP算法查找算法```pythondef kmp_search(text, pattern):def get_next(pattern):next = [0] len(pattern)next[0] = -1k = -1for j in range(1, len(pattern)):while k != -1 and pattern[k + 1] != pattern[j]: k = next[k]if pattern[k + 1] == pattern[j]:k += 1next[j] = kreturn nextnext = get_next(pattern)i = 0j = 0while i < len(text):if pattern[j] == text[i]:i += 1j += 1if j == len(pattern):return i - jelif i < len(text) and pattern[j] != text[i]: if j != 0:j = next[j - 1]else:i += 1return -1```3. Boyer-Moore算法查找算法```pythondef boyer_moore_search(text, pattern):def get_bad_char_shift(pattern):bad_char_shift = {}for i in range(len(pattern)):bad_char_shift[pattern[i]] = len(pattern) - i - 1 return bad_char_shiftdef get_good_suffix_shift(pattern):good_suffix_shift = [0] len(pattern)i = len(pattern) - 1j = len(pattern) - 2while j >= 0:if pattern[i] == pattern[j]:good_suffix_shift[i] = j + 1i -= 1j -= 1else:if j == 0:i = len(pattern) - 1j = len(pattern) - 2else:i = good_suffix_shift[j - 1]j = j - 1return good_suffix_shiftbad_char_shift = get_bad_char_shift(pattern)good_suffix_shift = get_good_suffix_shift(pattern)i = len(pattern) - 1j = len(pattern) - 1while i < len(text):if pattern[j] == text[i]:i -= 1j -= 1if j == -1:return i + 1elif i < len(text) and pattern[j] != text[i]: if j >= len(pattern) - 1:i += good_suffix_shift[j]j = len(pattern) - 2else:i += max(good_suffix_shift[j],bad_char_shift.get(text[i], -1))return -1```4. 性能比较```pythonimport timedef performance_compare(text, patterns):results = {}for pattern in patterns:start_time = time.time()result = violent_search(text, pattern)results[pattern] = (result, time.time() - start_time)start_time = time.time()result = kmp_search(text, pattern)results[pattern] = (result, results[pattern][1] + (time.time() - start_time))start_time = time.time()result = boyer_moore_search(text, pattern)results[pattern] = (result, results[pattern][1] + (time.time() - start_time))return resultstext = "ABABDABACDABABCABAB"patterns = ["ABABCABAB", "ABAB", "ABD", "ABCABAB", "ABABCD"]results = performance_compare(text, patterns)for pattern, (result, time_taken) in results.items():print(f"Pattern: {pattern}, Result: {result}, Time taken:{time_taken:.6f} seconds")```实验结果如下:```Pattern: ABABCABAB, Result: 0, Time taken: 0.000100 secondsPattern: ABAB, Result: 0, Time taken: 0.000100 secondsPattern: ABD, Result: 4, Time taken: 0.000100 secondsPattern: ABCABAB, Result: 6, Time taken: 0.000100 secondsPattern: ABABCD, Result: -1, Time taken: 0.000100 seconds```从实验结果可以看出,KMP算法和Boyer-Moore算法在查找效率上明显优于暴力法。

数据结构实验报告-基于字符串模式匹配算法的病毒感染检测问题

数据结构实验报告-基于字符串模式匹配算法的病毒感染检测问题

《数据结构》实验报告
abcd abcde abc def
00 输出结果为:
YES
NO 四、分析过程
在主函数中利用键盘输入 human[ ]、virus[ ],即 cin>>human>>virus; ,输入时要注意模 式串 virus 的长度不要超过主串 human 的长度。
调用 BF 子函数,输入的两个实参会送到 BF 算法里进行比较,当比较次数小于各自的长 度 时 , 开 始 匹 配 , 即 while(i<strlen(human)&&j<strlen(virus)) 。 如 果 模 式 串 和 主 串 相 同 human[i]==virus[j]时,i 和 j 都要加 1,否则 i=i-j+1; j=0;。当 j 等于 virus 的长度时,说明匹 配成功,令输出返回值 1;否则返回值为 0。
实验时间 实验地点 指导教师
年月日 电气楼 308
实验项目
实验类别
实 验 目 的 及 要 求
基于字符串模式匹配算法的病毒感染检测问题
基础实验
实验学时
4 学时
实验目的: 1.掌握字符串的顺序存储表示方法 2.掌握字符串模式匹配算法 BF 算法或 KMP 算法的实现
实验要求: 输入多组数据,每组数据占 1 行,输入 0 0 时结束输入;每组数据输
BF 算法的基本思想是:从主串的第 pos 个字符起与模式串的第一个字符比较,若相等, 则继续逐个比较后续字符;否则从主串的下一个字符起再重新和模式串进行比较。直至模式 串中的每一个字符和主串中的一个连续字符序列相同,则称匹配成功,否则不成功。
(1)首先全局定义了两个一定长度的数组用来存储人类和病毒的 DNA,分别是 human[100] 和 virus[100]。分别用 i 和 j 来指示主串 human 和模式串 virus 当前正待比较的字符位置。

KMP模式匹配算法的研究

KMP模式匹配算法的研究

其 中 nx[ ]=0若 nx[ et1 et ]=k 表 明 在 模 式 ,
串 中

Pl P …
’ = ‘ P
一P l ’ j


这 里 k为满 足 1<k< 的某 个 值 , 且 不 可 能存 在 并
法是 精 确 匹 配 , 中 基 本 的 算 法 是 经 典 B 其 F算 法 . K MP算 法是 一 种无 回 溯 的 算 法 , 率 有 较 大 提 高 , 效 但是 该算 法求 nx 函数 值 的定 义 过 于抽 象 , 且 还 et 而
YU e y n ZHANG a t n W n- a g, Lin-a g, DUAN hu mi S - n
( oeeo o p n fr n . H n nU i , a eg4 50 , hn ) C lg l fC m .adI o.E g , ea nv K  ̄n 70 4 C i n . a
Vo _ No. l22 5 0c .20 7 t o
文章编号 :04—17 (0 7 0 0 6 10 4 8 20 ) 5— 0 4—0 3
K MP模 式 匹 配 算法 的研 究
俞 文 洋 , 张连 堂 , 段 淑敏
( 南大 学 计 算机 与信 息工 程 学院 ,河 南 开 封 4 5 0 ) 河 704 摘要 : 通过 对字符 串模 式 匹配 K MP算 法的 分析 , 于 nx 和 nxvl 基 et et 函数 值 的意 义 , 出 了求 nxvl a 给 et a
河南省 开封 市人 , 河南 大学教授 , 士生导师, 硕 主要 研究方向 : 据库 、 数 数据挖掘 、 计算. 软
维普等 : MP模 式 匹 配 算 法 的 研 究 K

模式匹配实验报告

模式匹配实验报告

一、实验目的本次实验旨在让学生熟悉并掌握模式匹配的基本概念、算法及其应用。

通过实验,学生能够了解模式匹配算法的原理,掌握几种常见的模式匹配算法(如KMP算法、BF算法等)的实现方法,并能够运用这些算法解决实际问题。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 模式匹配基本概念- 模式匹配:在给定的文本中查找一个特定模式的过程。

- 模式:要查找的字符串。

- 文本:包含可能包含模式的字符串。

2. KMP算法- KMP算法(Knuth-Morris-Pratt)是一种高效的字符串匹配算法,其核心思想是避免重复比较已经确定不匹配的字符。

- 实现步骤:1. 构造一个部分匹配表(next数组)。

2. 遍历文本和模式,比较字符,并使用next数组调整模式的位置。

3. BF算法- BF算法(Boyer-Moore)是一种高效的字符串匹配算法,其核心思想是利用坏字符规则和好后缀规则来减少不必要的比较。

- 实现步骤:1. 计算坏字符规则。

2. 计算好后缀规则。

3. 遍历文本和模式,比较字符,并使用坏字符规则和好后缀规则调整模式的位置。

4. 模式匹配算法比较- 比较KMP算法和BF算法的时间复杂度、空间复杂度及适用场景。

四、实验步骤1. 初始化- 定义文本和模式字符串。

- 初始化模式匹配算法的参数。

2. 构造next数组(KMP算法)- 根据模式字符串构造部分匹配表(next数组)。

3. 计算坏字符规则和好后缀规则(BF算法)- 根据模式字符串计算坏字符规则和好后缀规则。

4. 遍历文本和模式- 使用KMP算法或BF算法遍历文本和模式,比较字符,并调整模式的位置。

5. 输出结果- 输出匹配结果,包括匹配的位置和匹配次数。

五、实验结果与分析1. KMP算法- 时间复杂度:O(nm),其中n为文本长度,m为模式长度。

- 空间复杂度:O(m)。

面向智能模式识别的模式匹配算法研究

面向智能模式识别的模式匹配算法研究

面向智能模式识别的模式匹配算法研究随着人工智能技术的不断发展和普及,智能模式识别已经成为人们生活中不可或缺的一部分。

而模式识别的核心算法之一就是模式匹配算法。

因此,研究面向智能模式识别的模式匹配算法显得十分必要。

一、传统模式匹配算法传统的模式匹配算法主要包括暴力匹配算法、KMP算法、BM算法、Sunday算法等。

其中,暴力匹配算法是最简单的一种算法,它的思路类似于人工匹配方式,即将模式串从头到尾与目标串进行比较。

由于它的时间复杂度为O(mn),其中m和n分别为目标串和模式串的长度,所以在实际应用中很少被采用。

KMP算法采用了一种称为“最长可匹配前后缀”的技术,大大提高了匹配效率。

BM算法在KMP算法的基础上进一步优化,它的时间复杂度为O(n),并且对于英文字符及其市面上较短的中文串可以有很好的效果。

SunDay算法也是一种优化算法,可以在O(n)的时间复杂度内实现字符串匹配。

这些传统的算法都能较好地解决模式匹配问题,但它们都有一个缺点,就是只考虑了字符本身的匹配,而忽略了字符之间的语义、上下文、关联等信息。

这些因素在实际应用场景中却十分重要。

二、面向智能模式识别的模式匹配算法为了更好地处理这种语义、上下文、关联等信息,一些新的面向智能模式识别的模式匹配算法应运而生。

这些算法能够更好地解决多种复杂的应用场景中的问题。

1. 深度学习算法深度学习算法是目前应用最广泛、效果最好的一种算法之一。

它通过神经网络层的设计,将输入数据逐层转化,直到将输入数据映射到一个向量空间中。

然后,使用向量空间中的相似度度量来计算输入数据之间的相似度或距离,进而达到匹配的目的。

深度学习算法在自然语言处理、图像识别、语音识别等领域取得了非常好的成绩。

2. 聚类算法聚类算法可将数据集中的同类数据分到同一个簇中,从而将数据量缩小,方便后续的匹配操作。

聚类算法在模式匹配中可以用来简化样本库,减少不必要的匹配操作。

此外,聚类算法还可以为模式匹配提供更多的特征信息,提高匹配准确度。

三种模式匹配算法的比较和分析

三种模式匹配算法的比较和分析

三种模式匹配算法的比较和分析模式匹配算法是计算机科学中常用的一种算法,用于在一个文本字符串中查找一个特定模式。

它在多个领域中都有广泛的应用,例如字符串匹配、图像处理和自然语言处理等。

在本文中,我们将比较并分析三种常见的模式匹配算法:暴力匹配算法、KMP算法和Boyer-Moore算法。

1.暴力匹配算法:暴力匹配算法也被称为朴素匹配算法,是一种最简单直接的模式匹配算法。

它的思想是从文本字符串的第一个字符开始,依次与模式字符串进行比较,直到找到匹配的位置或找遍整个文本字符串。

该算法的时间复杂度是O(mn),其中m是模式字符串的长度,n是文本字符串的长度。

优点:实现简单,容易理解。

缺点:效率较低,在处理大型文本字符串时不适用。

2.KMP算法:KMP算法是一种高效的模式匹配算法,它利用已匹配的信息减少比较次数。

该算法的核心思想是通过构建最大匹配长度表(也称为部分匹配表),根据部分匹配表中的信息来决定模式字符串的下一个比较位置。

这样可以跳过一部分已经匹配的字符,提高匹配的效率。

KMP算法的时间复杂度是O(m+n),其中m是模式字符串的长度,n是文本字符串的长度。

优点:能够在较短的时间内找到所有匹配的位置,适用于处理大型文本字符串。

缺点:算法实现稍复杂,需要构建部分匹配表。

3. Boyer-Moore算法:Boyer-Moore算法是一种高效的模式匹配算法,它通过利用模式字符串中的信息来进行跳跃式的比较,从而减少比较次数。

该算法分为两个阶段:坏字符规则和好后缀规则。

(1)坏字符规则:采用从模式字符串末尾到当前字符的顺序进行比较。

如果当前字符不匹配,则根据坏字符出现的位置和出现的最后位置进行移动。

(2)好后缀规则:利用模式字符串中的好后缀信息进行比较。

如果出现好后缀匹配的情况,则直接移动到匹配的位置,否则根据好后缀的后缀子串中的最长后缀与模式字符串的最长前缀进行比较。

Boyer-Moore算法的时间复杂度是O(m+n),其中m是模式字符串的长度,n是文本字符串的长度。

串匹配BM算法、KMP算法、BF算法

串匹配BM算法、KMP算法、BF算法

实验报告一串匹配问题{printf("success!\n");return 0;}}printf("no found!:%s\n\n",&t);return 0;}KMP算法:#include <stdio.h>#include <string.h>#include <conio.h>main(){char s[100];char t[100];}printf("no found!:%s\n\n",&t); return 0;}BM算法:#include <iostream>using namespace std;#include <stdio.h>#include <string.h>static int time=0;//dist函数int dist(char ch,char *T) {int k=-1,t1;}if(j==-1){cout<<"该串从第&i位开始匹配:"<<i+2<<endl;break;}else{time++;i=i+dist(S[i],T);}}if(i>=s1)cout<<"匹配不成功"<<endl;}void main(){int *next=new int;//给next指针分配空间char *S=new char;//给S指针分配空间char *T=new char;//给T指针分配空间cout<<"请输入串S:";cin>>S;cout<<"请输入串T:";cin>>T;cout<<"BM算法: ";BM(S,T);cout<<"一共执行循环"<<time<<"次"<<endl;}。

kmp算法测试用例

kmp算法测试用例

kmp算法测试用例KMP算法测试用例KMP算法是一种高效的字符串匹配算法,它能够在一个主串中快速查找一个模式串的位置。

在软件开发中,字符串匹配是一个非常常见的问题,如文本搜索、数据处理、编译器等都需要用到字符串匹配算法。

KMP算法以其高效的匹配速度和较低的时间复杂度成为了字符串匹配算法的首选之一。

一、KMP算法的原理KMP算法通过预处理模式串,构建一个部分匹配表(Partial Match Table),然后通过该表减少不必要的比较次数,提高算法的效率。

KMP算法的核心思想是,当在主串中匹配到某个字符与模式串不匹配时,通过部分匹配表找到一个可以跳过多个字符的位置,从而减少比较的次数。

二、KMP算法的实现KMP算法的实现分为两个步骤:预处理和匹配。

首先对模式串进行预处理,构建部分匹配表。

然后在主串中进行匹配,根据部分匹配表的结果决定移动的位置。

下面以一个测试用例来说明KMP算法的实现过程。

假设主串为:"ABABABABCABABABABCABABABABC",模式串为:"ABABABC"。

1. 预处理首先计算模式串的部分匹配表,该表用于存储模式串中每个前缀的最长相同前缀和后缀的长度。

例如,对于模式串"ABABABC",其部分匹配表为[0, 0, 1, 2, 3, 0, 1]。

2. 匹配在主串中按照KMP算法进行匹配。

首先将模式串与主串的第一个字符进行比较,发现不匹配,根据部分匹配表得到需要移动的位置。

由于模式串的第一个字符不匹配,根据部分匹配表的结果,移动的位置为3。

然后将模式串向右移动3位,与主串的第四个字符进行比较。

接下来的匹配过程如下:- 模式串与主串的第四个字符进行比较,发现不匹配,根据部分匹配表得到需要移动的位置为3。

将模式串向右移动3位,与主串的第七个字符进行比较。

- 模式串与主串的第七个字符进行比较,发现匹配,继续比较下一个字符。

KMP算法

KMP算法

KMP算法在传统的字符串匹配算法中,最常用的算法是朴素的模式匹配算法。

该算法的基本思想是:从主串的第一个字符开始,逐个字符地与模式串进行比较,如果发现不匹配的字符,则回溯到主串的下一个字符重新开始匹配。

这种算法的时间复杂度是O(m*n),其中m为主串的长度,n为模式串的长度。

在主串与模式串长度相等时,该算法的时间复杂度甚至会达到O(n^2)。

KMP算法的核心思想是利用模式串的信息,避免不必要的比较。

它通过预处理模式串,构建一个部分匹配表(prefix table),来提供匹配失败时的回溯位置。

这样,在匹配的过程中,只需要根据部分匹配表的内容来调整主串和模式串的位置即可。

这种优化使得KMP算法的时间复杂度降低到O(m+n)。

具体来说,KMP算法在预处理模式串时,对于模式串的每个前缀子串,求出其最长的相等的前缀和后缀的长度。

这个长度被称为部分匹配值。

例如,对于模式串"ababc",它的前缀子串有"","a","ab","aba",而其相等的后缀子串有"","c","bc","abc"。

其中,最长的相等的前缀和后缀的长度是2,因此,部分匹配值为2、在KMP算法中,这个信息会被存储在部分匹配表中,即prefix table。

当进行匹配时,如果发现匹配失败,那么根据部分匹配表中的值来进行回溯。

具体来说,如果当前字符匹配失败,那么将模式串向右移动的距离为:当前字符之前的最长相等前缀的长度-1、这样,就可以将模式串与主串对齐继续匹配。

1. 预处理模式串,求出部分匹配表(prefix table)。

2.根据部分匹配表,进行匹配操作。

3.如果匹配成功,返回匹配的位置;否则,返回匹配失败。

总之,KMP算法是一种高效的字符串匹配算法,通过预处理模式串,提供了匹配失败时的快速回溯位置。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四:KMP算法实验报告
一、问题描述
模式匹配两个串。

二、设计思想
这种由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现的改进的模式匹配算法简称为KM P算法。

注意到这是一个改进的算法,所以有必要把原来的模式匹配算法拿出来,其实理解的关键就在这里,一般的匹配算法:
int Index(String S,String T,int pos)//参考《数据结构》中的程序
{
i=pos;j=1;//这里的串的第1个元素下标是1
while(i<=S.Length && j<=T.Length)
{
if(S[i]==T[j]){++i;++j;}
else{i=i-j+2;j=1;}//**************(1)
}
if(j>T.Length) return i-T.Length;//匹配成功
else return 0;
}
匹配的过程非常清晰,关键是当‘失配’的时候程序是如何处理的?为什么要回溯,看下面的例子:
S:aaaaabababcaaa T:ababc
aaaaabababcaaa
ababc.(.表示前一个已经失配)
回溯的结果就是
aaaaabababcaaa
a.(babc)
如果不回溯就是
aaaaabababcaaa
aba.bc
这样就漏了一个可能匹配成功的情况
aaaaabababcaaa
ababc
这是由T串本身的性质决定的,是因为T串本身有前后'部分匹配'的性质。

如果T为a bcdef这样的,大没有回溯的必要。

改进的地方也就是这里,我们从T串本身出发,事先就找准了T自身前后部分匹配的位置,那就可以改进算法。

如果不用回溯,那T串下一个位置从哪里开始呢?
还是上面那个例子,T为ababc,如果c失配,那就可以往前移到aba最后一个a的位置,像这样:
...ababd...
ababc
->ababc
这样i不用回溯,j跳到前2个位置,继续匹配的过程,这就是KMP算法所在。

这个当T[j]失配后,j应该往前跳的值就是j的next值,它是由T串本身固有决定的,与S串无关。

《数据结构》上给了next值的定义:
0 如果j=1
next[j]={Max{k|1<k<j且'p1...pk-1'='pj-k+1...pj-1'
1 其它情况
其实它就是描述前面表述的情况,关于next[1]=0是规定的,这样规定可以使程序简单一些,如果非要定为其它的值只要不和后面的值冲突也是可以的;而那个Max是什么意思,举个例子:
T:aaab
...aaaab...
aaab
->aaab
->aaab
->aaab
像这样的T,前面自身部分匹配的部分不止两个,那应该往前跳到第几个呢?最近的一个,也就是说尽可能的向右滑移最短的长度。

到这里,就实现了KMP的大部分内容,然后关键的问题是如何求next值?先看如何用它来进行匹配操作。

将最前面的程序改写成:
int Index_KMP(String S,String T,int pos)
{
i=pos;j=1;//这里的串的第1个元素下标是1
while(i<=S.Length && j<=T.Length)
{
if(j==0 || S[i]==T[j]){++i;++j;} //注意到这里的j==0,和++j的作用就
知道为什么规定next[1]=0的好处了 else j=next[j];//i不变(不回溯),j跳动
}
if(j>T.Length) return i-T.Length;//匹配成功
else return 0;
}
求next值,这也是整个算法成功的关键。

前面说过了,next值表达的就是T串的自身部分匹配的性质,那么,我只要将T串和T串自身来一次匹配就可以求出来了,这里的匹配过程不是从头一个一个匹配,而是从T[1]和T[2]开始匹配,给出算法如下:void get_next(String T,int &next[])
{
i=1;j=0;next[1]=0;
while(i<=T.Length)
{
if(j==0 || T[i]==T[j]){++i;++j; next[i]=j;/**********(2)*/}
else j=next[j];
}
}
看这个函数非常像KMP匹配的函数!注意到(2)语句逻辑覆盖的时候是T[i]==T[j]以及i前面的、j前面的都匹配的情况下,于是先自增,然后记下来next[i]=j,这样每当i有自增就会求得一个next[i],而j一定会小于等于i,于是对于已经求出来的next,可以继续求后面的next,而next[1]=0是已知,所以整个就这样递推的求出来了,方法非常巧妙。

这样的改进已经是很不错了,但算法还可以改进,注意到下面的匹配情况:
...aaac...
aaaa.
T串中的'a'和S串中的'c'失配,而'a'的next值指的还是'a',那同样的比较还是会失配,而这样的比较是多余的,如果我事先知道,当T[i]==T[j],那next[i]就设为next[j],在求next值的时候就已经比较了,这样就可以去掉这样的多余的比较。

于是稍加改进得到:void get_nextval(String T,int &next[])
{
i=1;j=0;next[1]=0;
while(i<=T.Length)
{
if(j==0 || T[i]==T[j])
{ ++i;++j;
if(T[i]!=T[j]) next[i]=j;
else next[i]=next[j];//消去多余的可能的比较,next再向前跳 }
else j=next[j];
}
}
三、分析理论时间复杂性
这个程序或许比想像中的要简单,因为对于i值的不断增加,代码用的是for循环。

因此,这个代码可以这样形象地理解:扫描字符串S,并更新可以匹配到T的什么位置。

为什么这个程序是O(n)的? KMP的时间复杂度分析可谓摊还分析的典型。

我们从上述程序的j 值入手。

每一次执行while循环都会使j减小(但不能减成负的),而另外的改变j值的地方只有第五行。

每次执行了这一行,j都只能加1;因此,整个过程中j最多加了n个1。

于是,j最多只有n次减小的机会(j值减小的次数当然不能超过n,因为j永远是非负整数)。

这告诉我们,while循环总共最多执行了n次。

按照摊还分析的说法,平摊到每次for循环后,一次for循环的复杂度为O(1)。

整个过程显然是O(n)的。

这样的分析对于后面P数组预处理的过程同样有效,同样可以得到预处理过程的复杂度为O(m)。

四、原程序和调试结果
package kmp;
public class kmp {
String s="aaaaaaaa";
String p="aaaab";
int[] next=new int[s.length()];
//主要计算next[]的值
void calnext()
{
int i,j=0;
next[1] = 0;
next[0]=-1;
for(i=2;i<s.length();i++)
{
if(s.charAt(j)==s.charAt(i-1))
{
next[i]=next[i-1]+1;j++;
}
else
{
if(next[j]<0)
next[i]=0;
else
next[i]=next[j];
j=next[i];
}
}
}
//输出实际运算次数
void display()
{
int i=0,j=0,v;
int count=0;
while(i<s.length()&&j<p.length())
{
if(s.charAt(i)==p.charAt(j))
{
i++;j++;
}
else if(j==0)i++;
else j=next[j];
count++;
}
System.out.println(""+count);
}
public static void main(String[] args) { // TODO code application logic here
kmp k=new kmp();
k.calnext();
k.display();
}
}
五、对结果的分析
进行了12次匹配,匹配成功。

相关文档
最新文档