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。
模式匹配KMP算法实验报告

实验四: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个元素下标是1while(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:ababcaaaaabababcaaaababc.(.表示前一个已经失配)回溯的结果就是aaaaabababcaaaa.(babc)如果不回溯就是aaaaabababcaaaaba.bc这样就漏了一个可能匹配成功的情况aaaaabababcaaaababc这是由T串本身的性质决定的,是因为T串本身有前后'部分匹配'的性质。
如果T为a bcdef这样的,大没有回溯的必要。
改进的地方也就是这里,我们从T串本身出发,事先就找准了T自身前后部分匹配的位置,那就可以改进算法。
如果不用回溯,那T串下一个位置从哪里开始呢?还是上面那个例子,T为ababc,如果c失配,那就可以往前移到aba最后一个a的位置,像这样:...ababd...ababc->ababc这样i不用回溯,j跳到前2个位置,继续匹配的过程,这就是KMP算法所在。
串匹配算法实验报告

一、实验目的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;
KMP算法实验报告

}
六
第一步,对模式串中求next操作的逐一检查。
第二步:对KMP匹配算法进行逐一检查
七
八
j=next[j]; //消除了指针i的回溯
}
if(j==strlen(p))
return i+1-strlen(p);
}
return -1;
}
int main()
{
char s[100]="acabaabaabcacaabc";
char p[100]="baabcac";
printf("在第%d个元素时匹配成功\n",KMPMatch(s,p));
}
}
int KMPMatch(char *s,char *p)
{
int next[100];
int i,j;
i=0;
j=0;
getNext(p,next);
while(i<strlen(s))
{
if(j==-1||s[i]==p[j])
{
i++;
j++;
}
else
{
printf("此时主串是第%d个元素,%c。模式串是第%d个元素,%c\n",i+1,s[i],j+1,p[j]);
#include <stdlib.h>
#include <conio.h>
#defineCHUNKSIZE 80
void getNext(char *p,int *next)
{
int j,k,x;
next[0]=-1;
计算机算法实验报告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);}程序执行结果:查找到子串没有查到子串。
字符匹配查找实验报告(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算法在查找效率上明显优于暴力法。
模式匹配实验报告

一、实验目的本次实验旨在让学生熟悉并掌握模式匹配的基本概念、算法及其应用。
通过实验,学生能够了解模式匹配算法的原理,掌握几种常见的模式匹配算法(如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)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构
实
验
报
告
学院软件学院
年级2009级
班级班
学号
姓名
2010 年 3 月24 日
目录
一、实验内容 (1)
二、实验过程 (X)
三、实验结果 (X)
一、实验内容:
1、实验题目:KMP算法
2、实验要求:实现教材中字串比较kmp算法,比较模式串abaabcac与主串acabaabaabcacaabc。
3、实验目标:了解并掌握串的类型定义和基本操作,并在此基础上实现kmp算法。
了解kmp算法的基本原理和next函数的使用。
二、实验过程:
1、任务分配
2、设计思想
(1)KMP算法:在模式匹配中,每当一趟匹配过程出现字符比较不等时,不需要回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右滑动尽可能远的一段距离之后,继续进行比较。
(2)next函数:看成一个模式匹配问题,整个模式串既是主串又是模式串,可仿照KMP算法。
3、需求分析
(1) 输入的形式和输入值的范围:输入主串S,模式串T,位置pos
(2) 输出的形式:模式串在主串中开始匹配的位置i
(3) 程序所能达到的功能:利用kmp算法完成模式串和主串的模式匹
配,并输出模式串在主串中开始匹配的位置
(4) 测试数据:
S=acabaabaabcacaabc
T=abaabcac
Pos=6
4、概要设计
1).抽象数据类型
Class String()定义字符串
Int StrLength()返回串的长度
V oid get_next()求模式串T的next函数值并存入next
int kmp()利用模式串T的next函数求出T在主串S中第pos个字符之后的位置的KMP算法
2).算法
a.kmp算法模块:实现主串和模式串的模式匹配
b.next函数模块:实现模式串自身的模式匹配,并存入nxet函数中
c.接收处理命令(初始化数据)
5、详细设计
程序代码(含注释)
6、调试分析
(1)调试中的问题分析:
a.
(2)算法的时空分析:
在利用简单的Index()函数进行模式匹配时,虽然易于理解,但是该算法效率很低。
在某些特殊情况下,因为在主串中可能存在多个和模式串“部分匹配”的子串,因而引起指针i的多次回溯,从而导致时间复杂度过高。
对于kmp算法,每当一趟匹配过程中出现字符比较不等时,不需要回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右滑动尽可能远的一段距离之后,继续进行比较。
因此kmp算法的效率较高,时间复杂度也较低。
7、测试结果
列出你的测试结果,包括输入和输出。
这里的测试数据应该完整和严格,最好多于需求分析中所列。
8、说明(如果有)
三、实验结果:(结果分析,心得体会等)
1.结果分析
kmp算法的实验,既体现了字符串的定义原理和基本特点,又通过对字符串模式匹配实验的练习,得到了一种效率更高、时间复杂度更低的kmp算法
2.心得体会:这次kmp算法代码的编写给了我深刻的体会,它不仅让我了解了字符串的基本操作和相关知识点。
也通过字符串模式匹配实验的练习,让我学习了一种更为高效、时间复杂度更低的kmp算法。
注:共三大项,具体每一项的内容可根据自己的报告内容分条叙述,自行安排得当即可。
备注:(正文采用宋体小四,间距20磅)
以上说明仅供参考。
实验报告从这5部分展开,具体内容可自由发挥。
如有雷同,均按零分处理。